views:

45

answers:

2

This is a piece of code I had written in xcode

Foo * myFoo = [[Foo alloc] init] ;

[myFoo release] ;
[myFoo printMessage] ;

If I am right, it should give a runtime error when printmessage function is called as myFoo gets deallocated by that time. But in xcode , the code is working and print message is getting called, is it a problem due to setting on xcode?

Regards Abhijit

+7  A: 

You're invoking undefined behaviour by accessing freed memory.

It might crash, it might work fine, it might result in dancing unicorns spewing forth from your nose.

To detect memory errors whilst you're developing code, you should enable NSZombie's, see instructions here:

http://www.cocoadev.com/index.pl?NSZombieEnabled

Update

You might wonder why it works like this - surely the OS should always throw an error when you try to access memory that isn't valid?

The reason why you don't always get an error (and why the behaviour is undefined) is that checking the memory is valid on every access would result in a performance penalty - ie. the code would run slower, just to check for something that shouldn't ever happen.

Hence you must be careful to trap all these errors during development, so that they never happen for an end user. NSZombies is the best tool for finding them.

One other point - if you do "build and analyze" in xcode, it might also find this error at build time. Certainly the static analyzer will detect some memory errors at build time.

JosephH
+1 although I for one would not like to be spewing forth from somebody's nose.
BoltClock
hmm... ok , so is that undefined behavior valid on both device and simulator, I expect that app should throw an exception or send a message like "calling message on deallocated instance ?"
abhijit
You expect something to happen, but undefined behavior means even the compiler or your program won't know for sure what actually happens when you send a message to a released object. In this case I'm guessing sometimes the deallocation doesn't happen immediately.
BoltClock
Undefined behaviour is just that - it is not defined what will happen. If you enable NSZombies (which you should only do during development, not when releasing to customers) that will result in the "calling selector on deallocated instance" type messages. I'll add a bit more detail to my answer.
JosephH
A: 

Releasing an object is not instantaneous, the object will be released, but one can't be sure that it's when one sends a release message. The behavior you're experiencing is normal.

Yannick Compernol
Whilst you're correct in general, in the specific code given in this question I believe the dealloc call will happen synchronously in the release call - the object in question was never autoreleased, so cannot be in an autorelease pool. (I guess technically the init call could have got it into the autorelease pool, but I'd consider that unusual if it did.) Still, I should have mentioned it in my answer :)
JosephH