Hitting segmentation fault error with winapi

So I’m trying to port a simple 2D game engine written in C++ that uses the windows console text buffer to draw objects using characters. I got the thing to work right up until the last char is drawn, but it crashes soon after.

It seems like there is a continued attempt to read from the text buffer even after it has gotten to the end, or at least that is what I think is going on. The example I’m following places an escape character at the end of the buffer, '\0'. Something to do with c arrays being null-terminated or something like that, I don’t really know any C but I did a little research into it. Rust doesn’t seem to have that same requirements with its own arrays though. Is it because I’m assigning a c type from winapi?

I’d love it if someone could take a peek at my code and shed some light on what may be going on.

Summary
let buff_width = 2;
    let buff_height = 2;

    let buff_coord = wincontypes::COORD {
        X: 0,
        Y: 0,
    };

    let mut window_buffer: Vec<ctypes::wchar_t> = vec!['*' as u16; buff_width * buff_height];

    // let mut window_buffer: Vec<winnt::LPCWSTR> = vec![0 as *const u16; buff_width * buff_height];

    // let mut window_buffer: Vec<winnt::LPCWSTR> = vec![0 as *const u16; buff_width * buff_height];

    let dwBytesWritten = 0 as *mut u32;

    // window_buffer[buff_width * buff_height - 1] = '\0' as u16;

    unsafe {
        let hconsole = wincon::CreateConsoleScreenBuffer(winnt::GENERIC_READ | winnt::GENERIC_WRITE, 0, ptr::null(), wincon::CONSOLE_TEXTMODE_BUFFER, ntdef::NULL);

        wincon::SetConsoleActiveScreenBuffer(hconsole);

        //code crashes from this point on
        wincon::WriteConsoleOutputCharacterW(hconsole, window_buffer.as_ptr(), 2 * 2, buff_coord, dwBytesWritten);
    }

The code I’m trying to reproduce is from this video here: https://youtu.be/xW8skO7MFYw?t=182

The problem is that WriteConsoleOutputCharacterW is supposed to take a pointer to a variable to record how many bytes were written, but instead of passing a pointer to a variable, you’re passing a variable directly that is a null pointer. Instead of let dwBytesWritten = 0 as *mut u32;, you should do let mut dwBytesWritten = 0; and then when you call WriteConsoleOutputCharacterW you would pass in &mut dwBytesWritten.

@retep998 Hey, thanks for the response! Funny enough, you had already helped me with the answer in a way. A couple of weeks ago I scoured your gitter page and saw a post where you helped somebody with the GetUserNameW function. I messed around with that function using your suggestion and understood what the problem was eventually. I should of updated this post :sweat:

I have a question though. When I was first trying to get the function to work, the compiler was telling me the function expected type *mut u32, which I thought meant it was looking for a raw pointer to a value. You mentioned that I was passing a null pointer. Are raw pointers and null pointers the same thing? Or is it the 0 value that is making it null? Thanks again for the help!

0 as *mut u32 creates a raw pointer that is null. Meanwhile let mut x = 0; let ptr = &mut x as *mut u32 would create a raw pointer to x.

Ah, OK I think I see it a little more clearly now. It started to click after reading this and then the chapter on raw pointers in the O’Reilly book. Thanks a bunch for the explanation!