memory management revisited

iconara

Registered
<tt>

NSString *str;

str = [[NSString alloc] initWithString:mad:"string"];

str = [[NSString alloc] initWithString:mad:"string again"];

[str release];

</tt>


Does this create a memory leak? Should the variable <tt>str</tt> have been released beetween the allocations? I Think it should, but I don't think that it is obvious. Think about the same code in Java:

<tt>

String str;

str = new String( "string" );

str = new String( "string again" );

// the object moves out of scope and is freed by the GC

</tt>

in this code, when is the object containing "string" freed? Could it be that in Java, the memory holding the object is overwritten and in Cocoa/ObjC a new a new chunk of memy is used for the new object since we call +alloc. I don't think that I have understood all of the implications...


theo
 
I suspect you'd get an application crash if you tried to run that code.

It seems to me that neither of those alloc or init statements issues a retain message which means that the release statement is premature.

By convention, only "helper" messages like stringWithString or stringWithFile, etc automatically give a retain message, so if you create a string with an alloc and init then you have to retain it yourself.

In short, no, this is not a memory leak, but it is a premature release that may give you some nonsensical error and crash.

Others, please let me know if I'm mistaken.

-Rob
 
no I think you've got it all wrong rharder...

I belive that you mixed up the two, the -initWithString (accompanied by a +alloc) creates a new object which one does not have to retain to make it stick around, it will do so until you release it. The +stringWithString however is autoreleased and must be retained if you want to keep it.

<tt>
NSString *string = [[NSString alloc] initWithString:mad:"string];
</tt>

is a perfectly valid object creation which will allocate and initialize the string object. When it is sent a release message, it will disappear from memory again.

What you're thinking of is this:

<tt>
NSString *string = [NSString stringWithString:mad:"string"];
</tt>

which returns an autoreleased string object, this is often called a convenience constructor. If you send this object a release message, then you will end up with a SIGBUS or SIGSEGV sometime very shortly thereafter.

This is, however, not the same thing as my example above - and has nothing to do with it.
 
Ah, yes. That sounds right. Okay, I got it backwards.

The init... gives itself a retain message then?

-Rob
 
The objective C code you originally posted does create a memory leak. The reason is that you make two references to NSString objects and only send a release message to one of them. str is just a reference to a single NSString instance. You send the release message to the second of the two NSString objects that you allocate, and not the first NSString object, so the first NSString object persists beyond your sending of the release message to your instance variable str.

The reason why that doesn't happen in the java code is because the JVM releases all objects that go out of scope or aren't referenced by an instance varibale anymore.

Was that too convulated?

HTH,
F-bacher
 
ghoser>> that was exactly the answer I had in mid. thanks.

rharder>> well, no. +alloc is like retain (it increases the retain count by one), but the object is no good without an -init... so you always see these two together.




theo
 
Back
Top