The behaviour you are encountering is exactly as defined:
lpvBits [out]
A pointer to a buffer to receive the bitmap data. If this parameter is NULL, the function passes the dimensions and format of the bitmap to the BITMAPINFO structure pointed to by the lpbi parameter.
(Source: MSDN)
To summarize, you have to provide a non-zero pointer if you want GetDIBits()
to fill in the bits. It is your responsibility to allocate the required memory.