寻找EXC_BAD_ACCESS的原因 [英] Finding the cause of EXC_BAD_ACCESS

查看:82
本文介绍了寻找EXC_BAD_ACCESS的原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下初始化方法的类:

I have a class with the following init method:

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
        StateStack* s = [[StateStack alloc] init];
        state = s;
        [s push:NONE]; //<--EXC_BAD_ACCESS on load here
        [s release];
    }

    return self;
}

StateStack具有以下初始化代码:

And StateStack has the following init code:

- (id)init {
    self = [super init];
    if (self) {
        NSMutableArray* s = [[NSMutableArray alloc] init];
        stack = s;
        [s release];
        NSLog(@"%d",[stack retainCount]);
    }
    return self;
}

奇怪的是,如果我删除NSLog行,则EXC_BAD_ACCESS移至StateStack的dealloc方法:

Oddly, if I remove the NSLog line, the EXC_BAD_ACCESS moves to StateStack's dealloc method:

- (void)dealloc {
    [stack release]; //<--EXC_BAD_ACCESS
    [super dealloc];
}

四处搜寻似乎表明EXC_BAD_ACCESS是由过度释放引起的,但是我看不到我是如何过度释放了任何东西.有人知道原因是什么吗?

Searching around seems to suggest that EXC_BAD_ACCESS is caused by overreleasing, but I can't see how I've overreleased anything. Does anyone know what the cause might be?

推荐答案

在您的init函数中:

    StateStack* s = [[StateStack alloc] init];
    state = s;
    [s push:NONE]; //<--EXC_BAD_ACCESS on load here
    [s release];

您正在分配StateStack的实例;它的保留计数为1.然后,在调用release的函数结束时,保留计数变为0,并且可以释放对象了.因此,当以后执行dealloc时,会将state ivar发送给另一个release,这将导致错误的访问.您不需要释放s,因为您希望保留该状态.在另一种init方法中,会发生相同的错误模式.

you are allocating an instance of StateStack; this gets a retain count of 1. Then at the end of the function you call release, retain count goes to 0 and the object is ready to be released. So, when later dealloc is executed, the state ivar is sent another release and that is causing the bad access. You don't need to release s, since you want that state be retained. The same error pattern occurs in the other init method.

这是正确的:

- (id)init
{
  self = [super init];
  if (self) {
    // Initialization code here.
    StateStack* s = [[StateStack alloc] init];
    state = s;
    [s push:NONE]; //<--EXC_BAD_ACCESS on load here
  }

  return self;
}

- (id)init {
   self = [super init];
   if (self) {
     NSMutableArray* s = [[NSMutableArray alloc] init];
     stack = s;
   }
   return self;
 }

注意:我不想引起误会.使用保留计数检查正确的内存分配是没有用的.这是真实的.无论如何,根据保留计数进行推理有助于理解分配/释放/自动释放对象时发生的情况.这是基本的机制,但是要跟踪它的使用情况以检查内存管理的正确性太困难了.

NB: I don't want to generate misunderstandings. Using retain count to check for correct memory allocation is useless. This is true. Anyway, reasoning in terms of retain count helps understanding what happens when you allocate/release/autorelease an object. It is the basic mechanism, but it is too difficult to track it usage to check for correctness of memory management.

这篇关于寻找EXC_BAD_ACCESS的原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆