0

I was confused by such output result of this program.

#import <Foundation/Foundation.h>
#import "Human.h"

int main(int argc, const char * argv[]) {
    Human *human = [Human new];

    [human release];

    [human sayHello];

    return 0;
}

The class itself is

@implementation Human

-(void)sayHello {
    NSLog(@"Hello");
}

-(void)dealloc {
    NSLog(@"Deallocated");
   [super dealloc];
}

@end

The result is Output result

The main question is why method sayHello was executed though object itself was destroyed as its retain count was set to 0 by sending release message? What's more important that if I go through the program flow via debugger, the application will crash cause human pointer is not an object anymore. What's happening here?

P.S. ARC is turned off

Thanks in advance.

Dave
  • 5
  • 2
  • You're correct to expect a failure, but the two consecutive statements don't give the runtime time to reclaim the deallocated object. Let the run loop finish and reenter with, this: `[human performSelector:@selector(sayHello) withObject:nil afterDelay:0]`, and you'll see the failure that you expect – danh Aug 18 '18 at 19:00
  • Does memory fully release when run loop is finished? – Dave Aug 18 '18 at 19:08

1 Answers1

2

Welcome to C! There are no safety guards here.

When memory is deallocated, the compiler and runtime don't, by default, do anything special other than to mark the memory as available for use by something else.

Whatever is in the memory remains in the memory and, as you've discovered, said memory can still be read from and that can lead to very nasty bugs.

In Xcode, you can turn on zombie detection that would cause this particular bug to be highlighted at runtime by the tools.

There is also malloc scribbling/debugging, which would also catch this.

See here: https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html

bbum
  • 162,346
  • 23
  • 271
  • 359
  • Thanks so much! As I correctly understand you, memory pointer points to can be either object and not. And that’s sometimes will work or sometimes may cause a big problems when it crashes? It strictly depends on how operating system will handle memory that we released? – Dave Aug 18 '18 at 19:07
  • Pretty much! Specifically, when you cause an object to be `deallocated`, nothing clears out the memory that the object resided in. So, later attempts at messaging it will seemingly work, but it is a ticking time bomb. ARC defends against this a bit; things tend to be zeroed out on allocation more proactively. – bbum Aug 19 '18 at 04:22
  • Thanks! I got you. – Dave Aug 20 '18 at 16:27