Search code examples
c++winapic++11nullptr

Null function pointers in a new object aren't actually nullptr


I am using C++(11) w/ Visual Studio 2012.

I create windows using a custom made wrapper class.

CUIWindow* winA = new CUIWindow ( NULL, TEXT("winAClassName"), TEXT("winACaption"), 200, 300 );

Each window has a series of "sockets" for pluggabe events.

public:
    LPFNCUIWINDOWONCLOSE OnClose;
    LPFNCUIWINDOWONDESTROY OnDestroy;
    LPFNCUIWINDOWONNOTIFY OnNotify;
    LPFNCUIWINDOWONSIZE OnSize;
    LPFNCUIWINDOWONHOTKEY OnHotkey;

I use the following macro for calling the different sockets that can be assigned to my window class in the message loop:

#define MapEvent(e, fn) \
{ \
    case e: \
        if ( fn != nullptr ) \
            return static_cast<LPARAM>( HANDLE_##e((hWnd), (wParam), (lParam), fn) ); \
}

I have a situation as below;

Code with breakpoint

You can assume pWindow is a valid pointer to a CUIWindow object.

At the shown breakpoint some of the uninitialized OnXXXX events are defined as 0xCDCDCDCD and are getting called when their message arrives (regardless of me never actually explicitly setting them after class creation). This gives me an 0x0BADFOOD exception because the function pointer is bad. I would have assumed that null function pointers would have been caught by if ( fn != nullptr ) however now I am not so sure and I'm requesting help to;

  1. Explain why this is occurring
  2. Find the best way to stop this from occurring, preferably without explicitly setting all the function pointers to zero in the constructor since sometimes there are many, many, sockets.

Solution

  • Uninitialized pointers don't generally get set to a null pointer automatically. Is changing your class slightly an option? If so, you can set all of them without naming all of them.

    struct CUIWindowEvents
    {
        LPFNCUIWINDOWONCLOSE OnClose;
        LPFNCUIWINDOWONDESTROY OnDestroy;
        LPFNCUIWINDOWONNOTIFY OnNotify;
        LPFNCUIWINDOWONSIZE OnSize;
        LPFNCUIWINDOWONHOTKEY OnHotkey;
    }
    
    class CUIWindow
    {
    public:
        CUIWindowEvents Events; // move all events to a simple struct
    
        CUIWindow() // and in your constructor
            : Events() // initialise Events; this sets all the pointers to null
        { ... }
    };