tags:

views:

299

answers:

3
AlertEvent::AlertEvent(const std::string& text) :
    IMEvent(kIMEventAlert, alertText.c_str()),
    alertText(text)
{
    //inspection at time of crash shows alertText is a valid string
}


IMEvent::IMEvent(long eventID, const char* details)
{
    //during construction, details==0xcccccccc
}

on a related note, the monospace font looks really terrible in chrome, whats up with that?

+2  A: 

The IMEvent constructor is called before alertText's constructor is called. In particular therefore its argument alertText.c_str() is evaluated before alertText's constructor is called. This ain't good.

Initializer expressions are called in the order that the things being initialized are declared (not necessarily the order the initializers are listed). So parent classes first, then members. Compilers sometime helpfully warn you if you don't list the initializers in the order they will actually be executed. So provided you get that right, the rule is "don't use anything you haven't initialized". This code uses alertText before it is initialized.

Steve Jessop
wow, im asking really dumb questions today :)
Dustin Getz
+4  A: 

alertText may be shown as a string in a debugger, but it has not been constructed yet (and therefore alertText.c_str() will return an indeterminate pointer).

To avoid this, one could initialize use text.c_str() as an argument to the IMEvent ctor.

AlertEvent::AlertEvent(const std::string& text) :
    IMEvent(kIMEventAlert, text.c_str()),
    alertText(text)
{
    //inspection at time of crash shows alertText is a valid string
}


IMEvent::IMEvent(long eventID, const char* details)
{
    //during construction, details==0xcccccccc
}
Adam
The order of values in the initialization list is irrelavent. The member variables will be initialized in the same order they are declared in the class.
Martin York
Seconded: the first suggested fix doesn't work, and "ought to" provoke a compiler warning, because it results in the initializer expressions counter-intuitively being evaluated in a different order from the one they're listed.
Steve Jessop
The second suggested fix *might* be appropriate, or might not, depending what IMEvent::IMEvent does with its details parameter. If it stashes it away and expects it to persist any longer than the call to AlertEvent::AlertEvent returning, you may be out of luck.
Steve Jessop
Thanks for the corrections. I'll edit the post.
Adam
+1  A: 

The IMEvent constructor is called before alertText's constructor is called.

Almost. alertText.c_str() is called before alertText is constructed, that is the real problem. The easiest solution is replacing it with text.c_str()

Leon Timmermans
Sure, but I guessed that the faulty assumption was that alertText had been initialized at point of use. I've added this to my answer anyway, thanks.
Steve Jessop