-1

Unbelievable in Xcode 4.6.

If I initialize a variable to something, it frees the memory. But what if this variable has a random value ?

class X 
{

private:

    NSThread* thr;

public:

    X();
}; 
X :: X()
    {
        thr = 0; // BOOM !!!?
    }
X* x = new X(); // Constructor crashes.

But if the constructor is inline, it doesn't!

Hugo Dozois
  • 8,147
  • 12
  • 54
  • 58
Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78
  • How is it related to Xcode? Do you really think that it wouldn't do the same if you used another IDE? –  Feb 03 '13 at 12:26
  • In Xcode 4.5 it worked as expected. If it crashes in Xcode 4.6, how am I supposed to initialize the variables then? – Michael Chourdakis Feb 03 '13 at 12:28
  • 1
    @ericgorr They aren't. In C and C++, the constant numeric value `0`, when assigned or compared to a pointer, is implicitly treated as `NULL`. –  Feb 03 '13 at 12:32
  • It crashes when, for some reason, the "thr" isn't initialized to 0. I supposed that this was the default with ARC ? – Michael Chourdakis Feb 03 '13 at 12:42
  • I edited it. It crashes when the object is created with new. It crashes because, on new, the x->thr has a random value. Setting it to 0 causes ARC to try to release the old pointer, which is not valid. – Michael Chourdakis Feb 03 '13 at 12:46
  • Still doesn't crash for me. Provide more information. – zaph Feb 03 '13 at 12:48
  • Well I don't know what to try. In another project, the variables in the class are automatically initialized to 0, so it works. In this project, the variables in the class get random values and then it crashes on the constructor. – Michael Chourdakis Feb 03 '13 at 12:51
  • UPDATE: It doesn't crash when the constructor is inlined. Try the edited sample. When the constructor is not inline, it crashes. – Michael Chourdakis Feb 03 '13 at 12:59
  • 2
    Aren't you supposed to [initialize the member variable](http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr387.htm) like this in a C++ constructor? `X :: X() : thr(0) { }` – Kurt Revis Feb 03 '13 at 13:08
  • Your example will crash when thr is pointing to random memory on construction. This is not always the case. I solved it by inlining the constructor or to initialize it by thr(0). – Michael Chourdakis Feb 03 '13 at 13:17
  • Inlining the constructor may happen to work for you today, but I wouldn't depend on it. – Kurt Revis Feb 03 '13 at 13:31
  • Please let the question as a question and do not put the solution in the question once it's resolved. Also avoid putting solved in the title. See http://meta.stackexchange.com/questions/172501/community-edit-request-solved-fixed-answered – Hugo Dozois Apr 14 '13 at 19:31

1 Answers1

3

In a C++ constructor, you need to use an initialization list to set the initial value of the member variable.

X :: X() : thr(nil) 
{
}

Otherwise, like you are seeing, thr will initially have a garbage value, and you might crash when ARC tries to send -release to that value.

As the ARC documentation says:

ARC cannot differentiate between an assignment operator which is intended to “initialize” dynamic memory and one which is intended to potentially replace a value.

Community
  • 1
  • 1
Kurt Revis
  • 27,695
  • 5
  • 68
  • 74