tags:

views:

902

answers:

6

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++.

A: 

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
Sorry, forgot to put 'static' here. In our code, it is static.
Simon
+1  A: 

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

OneOfOne
A: 

The code as posted should initialise the map correctly. As you are obviously not posting the actual code (hence the static issue you corrected), it's hard to advise further. I can't emphasise more that when asking a question here you MUST post real code using copy & paste, not merely some approximation.

anon
It's not possible to post all our code for business reasons. I've posted as much as I think I can get away with.
Simon
Your competitors want to copy buggy code?
anon
If the actual code is proprietary, write a small example program which has the same problem.
dalle
No, but I want to obey my contract, not lose my job.
Simon
Of course you shall obey your contract, I'm just suggesting that you try to reproduce the same problem with another smaller but similar program in order to figure out why it doesn't work.
dalle
@dalle: Sorry, my comment was @neil. If I get time, I'll try your suggestion.
Simon
-1 you don't need the exact code to reproduce/analyze the problem
Polaris878
+3  A: 

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
A good point
anon
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
+1  A: 

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

ferrari fan
Only the second time (because it will be a duplicate) - and that will not cause the problem he's asking about.
anon
The problem happens whether or not the window handle is null.
Simon
+1  A: 

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