3

Ok I understand that this error mostly comes from sending a method call or trying to access a variable that has already been deallocated.

Here is the problem:

.h
@interface TimeEntry : NSObject <NSCopying, NSCoding> {

NSDate *from;
NSDate *to;

NSString *information;


}

@property (nonatomic, retain) NSDate *from;
@property (nonatomic, retain) NSDate *to;

@property (nonatomic, copy) NSString *information;

@end

And my classes' dealloc.

-(void)dealloc{

    [super dealloc];    
    [to release];
    [from release];
    [information release];

}

This is the traceback thing when I get the EXC_BAD_ACCESS error alt text

So I'm sending a message to an object that has been deallocated right?

So I turned on NSZombie and this STOPPED my crashes. It didn't give me some lovely crash report like I'd hoped. Instead it just kept the program from crashing.

In the dealloc method above if I comment out [to release] and [from release] the app doesnt crash. If I comment out just one of them.. it doesn't crash. In the debug window to and from have different memory addresses.

How can memory management be so hard!!!!

Any clues anyone?

Thanks,

Dan

Community
  • 1
  • 1
Dan Morgan
  • 2,500
  • 5
  • 25
  • 32

5 Answers5

13

Send the [super dealloc] message after you've released your variables, not before. [super dealloc] should be the last thing you do in your dealloc method.

Terry Wilcox
  • 9,010
  • 1
  • 34
  • 36
  • Why does it make a difference? – Himadri Choudhury Feb 18 '09 at 21:22
  • Because this is what Apple tells you to do ;) http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/dealloc – Michel Feb 18 '09 at 21:26
  • hehe thats the kind of annoying mistake I WILL NEVER MAKE AGAIN!!! can anyone elaborate on the theory behind this? – Dan Morgan Feb 18 '09 at 21:33
  • 3
    [super dealloc] is deallocating the memory your object occupies, including the pointers to your variables. – Terry Wilcox Feb 18 '09 at 21:42
  • Note: Only -[NSObject dealloc] actually frees the memory. In a deeper inheritance hierarchy, only the last call will dealloc the object itself. – Quinn Taylor Jun 11 '09 at 22:31
2

Notice that you can send [nil release] and the application will not crash. so checking for nil before releasing is some what unnecessary.

but i do agree that you should do [super dealloc] in the end of the dealloc procedure.

0

You should inspect all of the statements involving your properties to undestand where your variables are actually deallocated. Anyway, here is a quick solution that will avoid crashes, since your variables will be released if and only if they are still allocated objects:

-(void)dealloc{

if(to != nil{ 
   NSLog(@"releasing: %@", to);
   [to release];
}

if(from != nil{
   NSLog(@"releasing: %@", from);
   [from release];
}

if(information != nil){
   NSLog(@"releasing: %@", information);
   [information release];
}

[super dealloc]; 

}

Also, you may want to download, install and use the CLANG checker tool to understand why your code is wrong. This tool (which is already built for Leopard 10.5.x) may sometimes fail to provide the correct answer, but in my personal experience it never failed. I highly recommend it as one of your daily development tools.

You can download it from

http://clang.llvm.org/StaticAnalysis.html

Usage it really simple. Take a look at

http://clang.llvm.org/StaticAnalysisUsage.html#BasicUsage

In practice, you simply build your Xcode project using the command

scan-build -k -V xcodebuild

then, you inspect the resulting output HTML files using the command that will appears as output in your terminal window. These files will give you a detailed explanation of why something is wrong in your code.

Kind regards

Massimo Cafaro
  • 25,429
  • 15
  • 79
  • 93
  • 1
    The extra gunk in this dealloc method is absolutely unnecessary. In Objective-C, sending a message to nil is ignored — this isn't Java with NullPointerExceptions. I definitely recommend the Clang Static Analyzer, and it would catch this error, but it is obvious upon visual inspection, so long as you understand the idiom and know what to look for. – Quinn Taylor Jun 11 '09 at 22:33
0

Terry is correct, the [super dealloc] call must always be the last thing in -dealloc.

To be more specific, calling -[NSObject dealloc] is what deallocates the memory for the object. (In your case, you directly extend NSObject, but deeper inheritance trees create a chain of dealloc calls.) In a general sense, calling a parent's -dealloc method first will release resources inherited from the parent. If the child depends on any of those resources when it releases its own, you're up a creek. Since the parent cannot depend on the child, deallocing child resources first is the correct, safe way to do things.

Quinn Taylor
  • 44,553
  • 16
  • 113
  • 131
0

The properties of the current object are stored in the object.

When you call [super dealloc], you are telling the system to destroy the object. After that call, you cannot rely on the properties being there or correct any more.

As previously stated, call it after you release the other members.

Alex Brown
  • 41,819
  • 10
  • 94
  • 108