Reputation: 510
I have a problem with NSMutableArray
alloc and release. See below code:
NSMutableArray *enemiesToDeleteArray = [NSMutableArray arrayWithCapacity:5];
...
else if ([enemy isActive] && !CGRectIntersectsRect(fieldOfView, enemyRect))
{
[enemiesToDeleteArray addObject:enemy];
}
...
[enemiesToDeleteArray removeAllObjects];
[enemiesToDeleteArray release];
Above code crashes in a run. With a symbolic debug break error 'objc_release' or 'malloc_break_error'. Below I added backtrace from the occurence of objc_release error:
* thread #1: tid = 0x1c03, 0x01e140a5 libobjc.A.dylib`objc_release + 21, stop reason = EXC_BAD_ACCESS (code=1, address=0xa0020010)
frame #0: 0x01e140a5 libobjc.A.dylib`objc_release + 21
frame #1: 0x01e14bd9 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 555
frame #2: 0x023c6468 CoreFoundation`_CFAutoreleasePoolPop + 24
frame #3: 0x002effc1 QuartzCore`CA::AutoreleasePool::~AutoreleasePool() + 19
frame #4: 0x002ff35f QuartzCore`CA::Display::DisplayLink::dispatch(unsigned long long, unsigned long long) + 251
frame #5: 0x002ff75f QuartzCore`CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) + 161
frame #6: 0x023e3376 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
frame #7: 0x023e2e06 CoreFoundation`__CFRunLoopDoTimer + 534
frame #8: 0x023caa82 CoreFoundation`__CFRunLoopRun + 1810
frame #9: 0x023c9f44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #10: 0x023c9e1b CoreFoundation`CFRunLoopRunInMode + 123
frame #11: 0x0312b7e3 GraphicsServices`GSEventRunModal + 88
frame #12: 0x0312b668 GraphicsServices`GSEventRun + 104
frame #13: 0x009d0ffc UIKit`UIApplicationMain + 1211
frame #14: 0x000c81f6 MyAPP`main(argc=1, argv=0xbffff36c) + 134 at main.m:14
frame #15: 0x00001fa5 MyAPP`start + 53
and a backtrace from malloc_break_error:
MyAPP(18609,0xac98ea28) malloc: *** error for object 0x112dee40: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
(lldb) bt
* thread #1: tid = 0x1c03, 0x97be7815 libsystem_c.dylib`malloc_error_break, stop reason = breakpoint 1.1
frame #0: 0x97be7815 libsystem_c.dylib`malloc_error_break
frame #1: 0x97be8d51 libsystem_c.dylib`free + 346
frame #2: 0x023c5ea4 CoreFoundation`-[__NSArrayM dealloc] + 276
frame #3: 0x01e159ff libobjc.A.dylib`-[NSObject release] + 47
frame #4: 0x01e140d5 libobjc.A.dylib`objc_release + 69
frame #5: 0x01e14bd9 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 555
frame #6: 0x023c6468 CoreFoundation`_CFAutoreleasePoolPop + 24
frame #7: 0x002effc1 QuartzCore`CA::AutoreleasePool::~AutoreleasePool() + 19
frame #8: 0x002ff35f QuartzCore`CA::Display::DisplayLink::dispatch(unsigned long long, unsigned long long) + 251
frame #9: 0x002ff75f QuartzCore`CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) + 161
frame #10: 0x023e3376 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
frame #11: 0x023e2e06 CoreFoundation`__CFRunLoopDoTimer + 534
frame #12: 0x023caa82 CoreFoundation`__CFRunLoopRun + 1810
frame #13: 0x023c9f44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #14: 0x023c9e1b CoreFoundation`CFRunLoopRunInMode + 123
frame #15: 0x0312b7e3 GraphicsServices`GSEventRunModal + 88
frame #16: 0x0312b668 GraphicsServices`GSEventRun + 104
frame #17: 0x009d0ffc UIKit`UIApplicationMain + 1211
frame #18: 0x000c81f6 MyAPP`main(argc=1, argv=0xbffff36c) + 134 at main.m:14
frame #19: 0x00001fa5 MyAPP`start + 53
Please explain me someone, what am I doing wrong?
Upvotes: 0
Views: 517
Reputation: 3368
NSMutableArray *enemiesToDeleteArray = [NSMutableArray arrayWithCapacity:5];
returns an autoreleased instance, and that gets cleaned up some time after leaving the initializer. Now the pointer enemiesToDeleteArray points to undefined memory. You need to do:
enemiesToDeleteArray = [[NSMutableArray arrayWithCapacity:5] retain];
or
enemiesToDeleteArray = [[NSMutableArray alloc] initWithCapacity:5];
Upvotes: 2
Reputation: 6383
You should not release enemiesToDeleteArray
at all. It will get autoreleased at the end of the current scope. You didn't use alloc
at all, so this object is auto managed.
Upvotes: 4