3

I've made a message-only window class, and I'm trying to map HWNDs back to the objects with those handles. I'm trying to do that using a private static std::map<HWND, CMyClass*> belonging to the class, like this:

MyClass.h:

class CMyClass
{
    ...

private:
    HWND        m_hWnd;
    HINSTANCE   m_hInstance;
    LPCSTR      m_szClassName;

    static std::map<HWND, CMyClass*> s_mapHandles;

    ...
};

MyClass.cpp:

std::map<HWND, CMyClass*> CMyClass::s_mapHandles;

but when I try to add to the map, the program crashes. I've tried three different forms, and they all give the same error:

...
m_hWnd = ::CreateWindowEx(0, m_szClassName, "Message Window", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, m_hInstance, 0);
s_mapHandles.insert(pair<HWND, CMyClass*>(m_hWnd, this));

or

...
s_mapHandles.insert(s_mapHandles.end(), pair<HWND, CMyClass*>(m_hWnd, this));

or even

...
s_mapHandles[m_hWnd] = this;

In each case, there crash occurs at a call to _Root() which tries to return _Parent(_Myhead); _Parent(_Myhead) returns (_Nodepref)(*_Myhead)._Parent which fails because _Myhead is null.

How do I initialise the map, such that its head is non-null and I can insert things without it crashing? Apologies if I've explained this badly - I'm new to C++.

Simon
  • 25,468
  • 44
  • 152
  • 266

6 Answers6

6

Are you using it from the constructor of another statically initialized object?

Read C++ FAQ Lite - 10.12 What's the "static initialization order fiasco"?

dalle
  • 18,057
  • 5
  • 57
  • 81
  • I don't believe so, but that's an interesting (and horrible) problem that I'll look out for. Thanks for pointing it out! – Simon Jul 27 '09 at 13:55
1

You don't need to initialize it at all, it should be initialized by default.

OneOfOne
  • 95,033
  • 20
  • 184
  • 185
1

Just out of curiosity. Is the window handle not null? Because if the window handle comes back as null then the insert will fail.

Jaime Garcia
  • 6,744
  • 7
  • 49
  • 61
  • Only the second time (because it will be a duplicate) - and that will not cause the problem he's asking about. –  Jul 27 '09 at 14:21
  • The problem happens whether or not the window handle is null. – Simon Jul 28 '09 at 08:30
1

The original problem may be already solved, but I happen to run in to similar problem (without the static part). I used to have the map inside of a function, then moved it to a class variable. I also got crashes when inserting to the map. It turns out that I needed to delete the all the compiled objects and restart compiling from scratch. Then everything works as expected.

polyglot
  • 9,945
  • 10
  • 49
  • 63
0

My C++ is a little rusty, but I don't think there's any reason for having that line in your .cpp file. In fact, since it's not a static member, I'm not sure what kind of behavior that would lead to. But like I said, I'm rusty - I could be missing something.

Avdi
  • 18,340
  • 6
  • 53
  • 62
0

This has probably been solved in the meantime, but just for reference: Here is another solution for the actual problem behind the question: You can store custom data in the GWL_USERDATA field of any Window (I believe using the ::SetWindowLong API function if I remember correctly). If you put your CMyClass pointer in there instead of associating it with the HWND via a map, well, you don't need the map at all, and it is more efficient since all you need to do is typecast the pointer instead of an expensive map lookup.

Peter
  • 21
  • 1