Memory management with arrays
-
I have an array that is an instance variable. I'm trying to add an
object to it, and autorelease that object, so the next time this
happens, I can remove all objects in the array and the object will be
gone.
- (void)foo {
[array removeAllObjects];
Bar *bar = [[Bar alloc] init];
[array addObject:[bar autorelease];
}
This should remove all the objects, and add a new one. Basically, I
want the old Bar instance gone, and the new one in the array. However,
when I do this, I get an EXC_BAD_ACCESS when it tries to -
removeAllObjects. What's the problem? -
Hi Jacob,
On 2008-02-10, at 14:18, Jacob Bandes-Storch wrote:
> This should remove all the objects, and add a new one. Basically, I
> want the old Bar instance gone, and the new one in the array.
> However, when I do this, I get an EXC_BAD_ACCESS when it tries to -
> removeAllObjects. What's the problem?
Without seeing more code, I'd guess that you're not retaining the array.
Jonathon Mah
<me...> -
I am retaining the array when I create it initially, and releasing it
on dealloc.
On Feb 9, 2008, at 10:10 PM, Jonathon Mah wrote:
> Hi Jacob,
>
> On 2008-02-10, at 14:18, Jacob Bandes-Storch wrote:
>
>> This should remove all the objects, and add a new one. Basically, I
>> want the old Bar instance gone, and the new one in the array.
>> However, when I do this, I get an EXC_BAD_ACCESS when it tries to -
>> removeAllObjects. What's the problem?
>
>
> Without seeing more code, I'd guess that you're not retaining the
> array.
>
>
>
> Jonathon Mah
> <me...>
>
-
Hi, Jacob,
Maybe I'm missing something, but this "should work." I suspect that
the problem lies elsewhere in your code. Can you give us (the list) a
little more information on your file, such as relevant surrounding code?
Also, apologies if this is a basic question, but is your array
definitely declared and instantiated properly? and, additionally, is
it an NSMutableArray, and not a standard NSArray?
Cheers,
Andrew
On Feb 9, 2008, at 7:48 PM, Jacob Bandes-Storch wrote:
> I have an array that is an instance variable. I'm trying to add an
> object to it, and autorelease that object, so the next time this
> happens, I can remove all objects in the array and the object will
> be gone.
>
> - (void)foo {
> [array removeAllObjects];
> Bar *bar = [[Bar alloc] init];
> [array addObject:[bar autorelease];
> }
>
> This should remove all the objects, and add a new one. Basically, I
> want the old Bar instance gone, and the new one in the array.
> However, when I do this, I get an EXC_BAD_ACCESS when it tries to -
> removeAllObjects. What's the problem?
-
Here is my guess, just because i hit this recently. It had to do with
the [bar autorelease] call. This returns an autoreleased object. That
may not be valid when you cam back around to removeAllObjects. Try the
following:
void foo
{
[array removeAllObjects];
Bar* bar = [[Bar alloc] init];
[array addObject:bar];
[bar release];
}
the following should also work..
void foo
{
[array removeAllObjects];
Bar* bar = [[[Bar alloc] init] autorelease];
[array addObject:bar];
}
Scott
On Feb 9, 2008, at 7:48 PM, Jacob Bandes-Storch wrote:
> I have an array that is an instance variable. I'm trying to add an
> object to it, and autorelease that object, so the next time this
> happens, I can remove all objects in the array and the object will
> be gone.
>
> - (void)foo {
> [array removeAllObjects];
> Bar *bar = [[Bar alloc] init];
> [array addObject:[bar autorelease];
> }
>
> This should remove all the objects, and add a new one. Basically, I
> want the old Bar instance gone, and the new one in the array.
> However, when I do this, I get an EXC_BAD_ACCESS when it tries to -
> removeAllObjects. What's the problem?
-
On Feb 9, 2008, at 10:16 PM, Scott Andrew wrote:
> Here is my guess, just because i hit this recently. It had to do
> with the [bar autorelease] call. This returns an autoreleased
> object. That may not be valid when you cam back around to
> removeAllObjects. Try the following:
>
> void foo
> {
> [array removeAllObjects];
>
> Bar* bar = [[Bar alloc] init];
> [array addObject:bar];
> [bar release];
> }
>
> the following should also work..
>
> void foo
> {
> [array removeAllObjects];
>
> Bar* bar = [[[Bar alloc] init] autorelease];
>
> [array addObject:bar];
The OP's code, as posted, was fine. -autorelease returns the object
being autoreleased and alloc returns an object that has been retained.
Most likely, OP has overreleased one of the objects in the array. Run
with NSZombieEnabled to see what object is being overreleased.
Better yet, turn on malloc stack logging (no compact) and use
malloc_history to see allocation events at that address.
b.bum -
yay, one i THINK i can answer =)
I thought NSArray already automatically retained all objects that were
added to it?
then once the array is released (dealloced?) the objects within are
released as well
so you may only need to just send it an auto released object
so...
void foo()
{
[array removeAllObjects];
Bar *bar = [[Bar alloc] init];
[array addObject:bar];
}
that should work fine, shouldn't it?
please correct me if I'm wrong.
regards
Eric -
On Feb 9, 2008, at 10:57 PM, ss2 cire wrote:
> yay, one i THINK i can answer =)
>
> I thought NSArray already automatically retained all objects that
> were added to it?
> then once the array is released (dealloced?) the objects within are
> released as well
> so you may only need to just send it an auto released object
>
> so...
>
> void foo()
> {
> [array removeAllObjects];
> Bar *bar = [[Bar alloc] init];
>
> [array addObject:bar];
> }
>
>
> that should work fine, shouldn't it?
>
> please correct me if I'm wrong.
Double retain.
[array removeAllObjects]; // leaks the doubly-retained bar
b.bum -
Oh, that's true....
so change [array addObject:bar] to...
[array addObject:[bar autorelease]];
and that really should do it, but like others have said, there's
probably something else going on
with the code... is there anything more you can send us? maybe use a
paste site to hold the code?
regards,
Eric
On Feb 9, 2008, at 11:02 PM, Bill Bumgarner wrote:
> On Feb 9, 2008, at 10:57 PM, ss2 cire wrote:
>> yay, one i THINK i can answer =)
>>
>> I thought NSArray already automatically retained all objects that
>> were added to it?
>> then once the array is released (dealloced?) the objects within are
>> released as well
>> so you may only need to just send it an auto released object
>>
>> so...
>>
>> void foo()
>> {
>> [array removeAllObjects];
>> Bar *bar = [[Bar alloc] init];
>>
>> [array addObject:bar];
>> }
>>
>>
>> that should work fine, shouldn't it?
>>
>> please correct me if I'm wrong.
>
> Double retain.
>
> [array removeAllObjects]; // leaks the doubly-retained bar
>
> b.bum
>
-
True.. (late night). So basically. Put a break in bar's dealloc. See
were the extra dealloc is cooming from.
Scott
On Feb 9, 2008, at 10:38 PM, Bill Bumgarner wrote:
> On Feb 9, 2008, at 10:16 PM, Scott Andrew wrote:
>> Here is my guess, just because i hit this recently. It had to do
>> with the [bar autorelease] call. This returns an autoreleased
>> object. That may not be valid when you cam back around to
>> removeAllObjects. Try the following:
>>
>> void foo
>> {
>> [array removeAllObjects];
>>
>> Bar* bar = [[Bar alloc] init];
>> [array addObject:bar];
>> [bar release];
>> }
>>
>> the following should also work..
>>
>> void foo
>> {
>> [array removeAllObjects];
>>
>> Bar* bar = [[[Bar alloc] init] autorelease];
>>
>> [array addObject:bar];
>
> The OP's code, as posted, was fine. -autorelease returns the
> object being autoreleased and alloc returns an object that has been
> retained.
>
> Most likely, OP has overreleased one of the objects in the array.
> Run with NSZombieEnabled to see what object is being overreleased.
> Better yet, turn on malloc stack logging (no compact) and use
> malloc_history to see allocation events at that address.
>
> b.bum
>
-
On Feb 10, 2008, at 5:36 AM, Scott Andrew wrote:
> True.. (late night). So basically. Put a break in bar's dealloc. See
> were the extra dealloc is cooming from.
>
> Scott
There won't be an "extra dealloc" -- once dealloc'd, the object is
dead. There is an extra -release coming first, but breaking on -
release won't help, either as the object is dead by the time it happens.
As I said, run the app with "-NSZombieEnabled YES". This will cause
a proxy to be dropped into memory in place of every dealloc'd object
and said proxy will warn when messaged (because it should never be
messaged).
b.bum -
I put some useful breakpoints on http://www.cocoadev.com/index.pl?NSZombieEnabled
. I found these scattered about the web and collected them onto the
page.
On Feb 10, 2008, at 11:39 AM, Bill Bumgarner wrote:
> On Feb 10, 2008, at 5:36 AM, Scott Andrew wrote:
>> True.. (late night). So basically. Put a break in bar's dealloc.
>> See were the extra dealloc is cooming from.
>>
>> Scott
>
> There won't be an "extra dealloc" -- once dealloc'd, the object is
> dead. There is an extra -release coming first, but breaking on -
> release won't help, either as the object is dead by the time it
> happens.
>
> As I said, run the app with "-NSZombieEnabled YES". This will
> cause a proxy to be dropped into memory in place of every dealloc'd
> object and said proxy will warn when messaged (because it should
> never be messaged).
>
> b.bum



