I get a memory error in chapter 4


#1

I’ve followed the instructions of chapter 4 until page 72. When I run the app, I’ve got a EXC_BAD_ACCESS error (code 13, address 0x0). This error is in the objc_release. I suppose there’s a nil pointer somewhere.

[code]int main(int argc, const char * argv[])
{
@autoreleasepool
{ NSDate *now = [NSDate date];
NSCalendar *myCalendar = [NSCalendar currentCalendar];
NSDateComponents *weekComponents = [[NSDateComponents alloc] init];
NSMutableArray *myArray = [[NSMutableArray alloc] init];

	srandom((unsigned) time(NULL));
	
	for(int indx = 0; indx < 10; indx++)
	{	NSDate			*localWeeksFromNow;
		lotteryEntry	*localEntry;
		
		[weekComponents setWeek:indx];
		
		localWeeksFromNow = [myCalendar dateByAddingComponents:weekComponents toDate:now options:0];
		localEntry = [[lotteryEntry alloc] initWithEntryDate:localWeeksFromNow];
		
		[myArray addObject:localEntry];
		[localEntry release];
	}
	
	[now release];
	[weekComponents release];
	
	for(lotteryEntry *anEntry in myArray)
		NSLog(@"%@", anEntry);
	
	[myArray release];
}

return 0;

}[/code]

In the debugger the error appears after the last statement in the main function and I don’t understand why. I’ve tried to comment the line [myArray release] but the error remains.


#2

Can you actually compile this code, let alone run it to get that error?

It looks as though you haven’t posted all of your code.


#3

Yes, of course, I can compile the code without error. The error appears during execution. I’ve posted all the code of the main function.

I’ve made a copy and past of the code that I have posted here in the Xcode project, I can compile the code and run it.


#4

When I comment the line [now release]; by adding //, all works fine. But I don’t understand why because now has been allocated before :

When I type “po now” in the debugger just before releasing weekComponents, now is a valid pointer.


#5

Oh, I see now.

That’s because the statement:

NSDate *now = [NSDate date];

gives you an autoreleased object.

So when you release it again:

[now release];

you are trying to release an autoreleased object.

Oops:

//  main.m

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        NSDate *now = [NSDate date];
        [now release]; // oops!
    }
    return 0;
}

You can either don’t release the autoreleased object or retain it before releasing it.

Don’t release:

//  main.m

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        NSDate *now = [NSDate date];
    }
    return 0;
}

Retain first before releasing:

//  main.m

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        NSDate *now = [[NSDate date] retain];
        [now release];
    }
    return 0;
}

#6

Thank you for the answer.

A little change in the code leads to a big problem !