views:

79

answers:

3

Hello !
This is a (very) simplified version of my iPhone code :

@interface x {
NSString * name1;
NSString * name2;
}

-init {
name1 = @"";
name2 = @"";
}

-(void) a {
Foo * foo = [Foo alloc];
name1 = @"uhuh";
name2 = [foo bar]; // return a (NSString *)
[foo release];
}

-(void) b {
NSLog(@"%@", name1); // it works
NSLog(@"%@", name2); // there I get an EXC_BAD_ACCESS...
}

Why I have this problem ? And how can I solve it ?
Thanks !

Edit: I juste solve the problème, I forgot a "retain"...

A: 

I was getting an EXC_BAD_ACCESS error yesterday. It turned out I was calling release on an object which resulted in it being deleted, then I tried to use it.

You're not calling release on anything you're not supposed to are you?

Just a friendly reminder: if you don't call alloc or retain on an object, you don't call release. With the code you have provided, it doesn't appear this is the problem. But I wanted to point this out just in case.

Joel
A: 

Joel is correct. try to look your [foo bar] function, may be in that function you are releasing any object

Nnp
+1  A: 

You need to read the Cocoa Memory Management Guide.

Some of the things you're doing in the code show that you don't have a grasp on the fundamental concepts of cocoa memory management.

For instance:

[Foo alloc];

You're not initialising 'foo'. It's common practise to couple alloc and init calls together, eg: [[Foo alloc] init]; This will ensure the objects members and state is what you expect after creation.

name2 = [foo bar]; // returns a (NSString *)

The bar method is likely to return an autoreleased string. You're not retaining it after assigning it to name2, so it's going to be deallocated some time after the method returns. And this is why your code is crashing. You're trying to access a deallocated object. The object that name2 was pointing at was released and deallocated, but the pointer was not set to nil, which means the memory it's pointing at can now contain anything. It's undefined.

The reason name1 is working is because of a special consideration to do with using literal @"" strings in Cocoa. When a string is used like this, it becomes 'internalised'. If you create two literal strings that contain the same text, the system will optimise it so that both of those strings point to one object in memory.

That is to say that if you have code that looks like this:

NSString *myString1 = @"hello";
NSString *myString2 = @"hello";

NSLog(@"string1: %p, string2: %p", myString1, myString2);

it would result in a message looking like: string1: 0x123456, string2: 0x123456. The important thing to notice here is that the memory addresses are the same. The strings are pointing at the same object, even though they are different instances in the code.

Jasarien