Re: Two arrays sharing the same adress space.
Re: Two arrays sharing the same adress space.
- Subject: Re: Two arrays sharing the same adress space.
- From: Andy Lee <email@hidden>
- Date: Mon, 17 Nov 2008 07:13:26 -0500
On Nov 17, 2008, at 1:03 AM, Stephen J. Butler wrote:
On Sun, Nov 16, 2008 at 11:52 PM, Sandro Noel <email@hidden>
wrote:
as it turns out. with the bug fixed the mounts array is left null
because
the file does not exist yet.
so further in the program is i try to add to the array, nothing
happens.
and if i try "mounts = [[NSMutableArray alloc] init];" only the two
arrays
get the same pointer.
Well, then what's happening is obvious. initWithContentsOfFile: fails
because the file doesn't exist, so it performs cleanup (aka, call
release) and returns null. Your next alloc then just happens to grab
the same memory block.
1) never call the init* methods twice on the same object.
2) always use the value returned from an init* method.
To elaborate, the reasons for these are based in the way init methods
work:
A) When init methods fail, by convention they release their memory
and return nil so the caller knows they failed.
B) When init methods succeed, they may return a different object
than the original receiver.
To spell this out:
mounts = [[NSMutableArray alloc] init];
This allocates and initializes an empty NSMutableArray. Fine.
[mounts initWithContentsOfFile:someFile]];
There are two possible cases here.
A) If initWithContentsOfFile: fails, it releases the NSMutableArray,
which in this case causes the memory to be deallocated, and returns
nil. However, you're ignoring the return value, so mounts is now
pointing to a deallocated block of memory.
B) If initWithContentsOfFile: succeeds, your program *might* proceed
just as you expect. However, it is *very* possible that it returns an
object with a different address than mounts had before the call. So
mounts *may* still point to a perfectly valid NSMutableArray, but not
the one that contains your file contents. It's also conceivable that
the original object gets corrupted by the double init (well, we could
look at the source for NSMutableArray, but in the general case,
there's no requirement that double inits always be safe).
bonjourServices = [[NSMutableArray alloc]init];
What happened to you is that the memory formerly used by mounts
happened to be reused to create bonjourServices. So now you had two
variables that point to the same perfectly good NSMutableArray. Note
that if bonjourServices was some other kind of object -- for example,
a dictionary or a string -- you would have gotten a crash at some
point when you tried to send a message to either mounts or
bonjourServices that it didn't understand.
The best way to follow Stephen's rules 1 and 2 is to always, *always*
combine the alloc and init. Even though the following would have
worked (assuming you added the check for a nil return)...
mounts = [NSMutableArray alloc];
mounts = [mounts initWithContentsOfFile:someFile]];
...it's just too easy to forget the assignment in the second line.
Also, it would be easy to double-initialize by mistake. And finally,
it would be jarring to any other Cocoa programmer reading your code,
since the combined alloc/init is the established idiom.
--Andy
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden