Weston
Weston

Reputation: 1491

Memory Management Questions

I have been programming in Objective-C for a couple weeks now, and I think its time that I think more about my memory management and so I have a couple scenarios I would like clarification on.

NSString *myString = @"Hello, World";

If I were to on the next line do

NSString *anotherString = myString;

Is it getting copied? or is another string just a pointer to myString? if it's just a pointer how would I make anotherString a copy of myString that has its own memory?

What if I were to

[anotherString release];

What actually gets released, just anotherString, or does myString go away too?

Then if I were to do

anotherString = nil;

Does that actually free up memory and for use or does it still have the space allocated with empty memory? Obviously the pointer can still be used. What does it do to myString?

This will really help me become better at managing the memory properly, instead of just [object release]; randomly and causing crashes.

Thank you VERY MUCH in advance to whoever replies.

Upvotes: 0

Views: 62

Answers (3)

aroth
aroth

Reputation: 54806

When you do:

NSString *myString = @"Hello, World";
NSString *anotherString = myString;

...you're creating a single NSString instance, and two pointers to it. So to answer your questions, no it is not being copied. Yes, anotherString is just a pointer, and so is myString, the actual NSString instance is off in memory-land, at the address that both pointers are now pointing to.

To make a copy of the string, you would do:

NSString *anotherString = [myString copy];

When you do:

[anotherString release];

The NSString instance that anotherString points to is released. Nothing happens to anotherString itself. It continues to point to your now-invalidated object instance. If myString was pointing to the same instance, then yes, this causes myString to "go away" as well.

And if you do:

anotherString = nil;

...then you've caused a memory leak, because you reassigned the pointer without releasing the thing it was pointing at. Except not in this case because @"Hello, World" is a literal value that is loaded onto the stack and is not retained by your code.

In any case, setting anotherString to nil does nothing to your string, it just changes what anotherString points to. Your actual NSString instance is still off in memory-land, completely unaware that you just threw away your reference to it (possible exception: reference counted/garbage collected environments).

And yes, calling [object release] randomly will cause crashes. As a general rule you should only call release on something if:

  1. You called alloc and init... on it.
  2. You called retain on it.
  3. You obtained the object as a result of calling copy on some other object.

Note that these stack, so if you alloc something, retain it, and then copy it, you need to have 3 calls to release, two for the object that you alloc'ed, and one for the copy.

As a side note, you may find it clearer to write your object declarations like:

NSString* myString = @"Hello, World";
NSString* anotherString = myString;

...which makes it more obvious that what you are declaring are pointers to NSString's and not NSString's themselves. Personally I think your original syntax, while commonly used, is also backwards.

Upvotes: 2

Girish Kolari
Girish Kolari

Reputation: 2515

NSString *anotherString = myString;

--- This is just a pointer assignment

--- You can copy myString using [myString copy]

[anotherString release];

--- You are releasing the owner ship of the anotherString (please read about retain count concept)

anotherString = nil;

--- you are just assigning the pointer to nothing.

I suggest Please read more about memory management apple documents ...

Upvotes: 0

Morten Fast
Morten Fast

Reputation: 6320

This string:

NSString *myString = @"Hello, World";

is created on the stack. It's loaded into memory when the app starts. You don't own the memory backing the object, and therefore shouldn't release it.

If you want to copy a string to the heap (where you can manage the memory), you simply do this:

NSString *anotherString = [myString copy];

Then you're responsible for releasing that object when you're done with it.

[anotherString release];

Setting a pointer to nil just clears the pointer, not the object it's pointing to. It's still in memory.

Upvotes: 0

Related Questions