“EXC_BAD_ACCESS:无法恢复先前选择的帧” - 堆栈变量没有被清理

发布于 2025-01-05 19:54:31 字数 2048 浏览 0 评论 0原文

参考此处的问题。

该线程中提供的解决方案包括:

  1. 明智地声明您声明的变量将进入堆栈的位置和数量。
  2. 如果需要,禁用 Guard Malloc。

另外,一般来说: 3. 确保你正在释放一个你实际分配了内存的变量!

我没有上述问题。我在函数中使用的堆栈分配变量非常少,比如每个函数中使用 2-3 个。但由于这些函数在循环中调用了多次,因此似乎会触发异常。

更重要的是,这不仅发生在静态分配的变量上,堆上的东西也发生了!我在循环内使用了几个 NSNumber 变量的自动释放声明,以及每次调用时在函数范围内明智地分配和释放的字典时,出现了页面错误。

那么为什么会发生这种情况,为什么堆变量会受到影响呢?我完全不明白,请大家解释一下。 :)

我使用的是带有 XCode 4.2 的 IOS5、iPhone/iPad 模拟器。

谢谢!

问候, 开发

编辑:示例代码 <代码>
- (void)doSomething {
NSInteger fun = 3;
NSInteger 时间 = 4;
NSInteger 重载 = fun*time;
NSString *string = [NSString stringWithFormat:@"%d",重载];
NSObject *myCustomObject = [[NSObject alloc] init];
[myCustomDictionary setObject:myCustomObject forKey:string];
[myCustomObject 发布];
//myCustomDictionary 是一个 iVar,在类的 init 方法中分配,并在 dealloc 中释放,并且在其间的任何地方都没有触及
}
//doSomething 在执行过程中随着视图状态的变化、用户与其交互等被调用多次,通常在一次状态变化期间调用 2-3 次。

代码故意含糊不清,但同时,它与示例中一样简单。整个项目中的其余代码也是如此。几个函数,每个函数都做少量的工作,就像这个函数一样在内存方面很好地独立。

我之前遇到过 EXC_BAD_ACCESS 问题,当时参考了 这个问题。然而,就我而言,我没有在循环内的堆栈上创建多个变量,它们是由在执行过程中多次调用的函数重复创建的。理想情况下,变量应该在函数作用域结束时被销毁。不知道为什么那没有发生。

不管怎样,为了解决这个问题并防止发生多次分配,我最终将堆栈分配的变量声明为全部静态。这是不好的做法,但这正是我必须做的才能让它发挥作用。它一直有效,直到我最终再次遇到“doSomething”功能的问题。

因此,“doSomething”的困难在于,我不仅创建了堆栈分配的变量,还创建了堆内容。因此,我首先开始在 NSInteger 变量上获取 EXC_BAD_ACCESS,此时我尝试通过将它们声明为静态来再次修复它。它起作用了,但现在 EXC_BAD_ACCESS 开始出现在自动释放的变量上,最后出现在自定义分配的变量上 - 这就是我被难住的时候。我一直遵循内存管理的所有规则,并且堆栈和堆变量困扰着我。如果它只是堆东西,或者在循环内堆叠东西,我可以理解某个地方有错误。但在这里,两者都不是,这些是完全无辜的变量,在一个不在循环中调用的函数内部的堆栈上分配,以及永远不会从代码中的另一位置向它们抛出保留或释放的常规自动释放变量。更糟糕的是,故障点是随机的 - 不仅在这个函数中,而且在项目执行过程中几乎每一个被多次调用的点都是随机的。

Edit2:事实证明,在这种情况下,这是我的错。详情请参阅我的回答。很抱歉浪费了人们的时间。 :\

With reference to the question here.

The solutions provided in that thread, include:

  1. Being smart about where and how many variables you declare, that would go on the stack.
  2. Disable Guard Malloc if needed.

Also, in general:
3. Make sure you are releasing a variable you have actually allocated memory for!!

I have none of the above issues. There are very few stack-allocated variables that I use within functions, say 2-3 within each. But because the functions are called in a loop several times, it seems to trigger an exception.

And here's the kicker, this is not just happening for statically allocated variables, but stuff on the heap too! I'm getting the page errors on Auto-released declarations of NSNumber variables that I use a couple of inside the loop, as well as a dictionary that I juDIciously alloc and release within the scope of the function, every single time it's called.

So why is this happening, and why the heck are heap variables getting affected? I don't get it at all, please throw some light on this. :)

I'm on IOS5 with XCode 4.2, iPhone/iPad simulator.

Thanks!

Regards,
Dev

Edit: Sample code

- (void)doSomething {
NSInteger fun = 3;
NSInteger time = 4;
NSInteger overload = fun*time;
NSString *string = [NSString stringWithFormat:@"%d",overload];
NSObject *myCustomObject = [[NSObject alloc] init];
[myCustomDictionary setObject:myCustomObject forKey:string];
[myCustomObject release];
//myCustomDictionary is an iVar, alloced in the class's init method, and released in dealloc and not touched anywhere in between
}
//doSomething gets called several times through the course of execution as the state of the view changes, the user interacts with it etc, often 2-3 times during one state change.

The code is purposely vague, but at the same time, it is EXACTLY as simple as in the sample. As is the rest of the code in the entire project. Several functions, each doing a small amount of work, as nicely self contained memory-wise as this one.

I faced EXC_BAD_ACCESS issues before, and at that point had referred to this question. However in my case, I was not creating multiple variables on the stack within a loop, they were getting created repeatedly by a function which gets called several times through the course of the execution. Ideally, the variables should have just got destroyed at the end of function-scope. Not sure why that didn't happen.

Anyway, to resolve that and to prevent multiple allocations from happening, I ended up declaring my stack-allocated variables as all static. That is bad practice, but that's exactly what I had to do to get it working. And it was working until I ended up facing the issue AGAIN with the "doSomething" function.

So the difficulty in "doSomething", was that I did not have only stack-allocated variables getting created, but heap stuff too. So I first started getting EXC_BAD_ACCESS on the NSInteger variables, at which point I tried fixing it again, by declaring them as static. It worked, but now EXC_BAD_ACCESS started occurring on the auto-released variable and finally the custom-allocated variable - which is when I got stumped. I have been following all the rules of memory management, and I'm having stack AND heap variables fubaring all over me. If it was only heap stuff, or stack stuff inside a loop, I could understand there's a mistake SOMEwhere. But here, it's neither, these are perfectly innocent variables getting allocated on the stack inside ONE function that is NOT called in a loop, and regular auto-released variables that never ever get retains or releases thrown at them from another place in the code. What makes it all even worse, is that the failure points are random - not just in this function but practically every one that gets called several times through the course of execution of the project.

Edit2: Turns out, in this case, it's my fault. See my answer for details. Sorry for wasting people's time. :\

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

够运 2025-01-12 19:54:31

如果没有看到整个堆栈跟踪,我们无法真正帮助您。
EXC_BAD_ACCESS 没有任何意义,为了排除故障,我们需要知道异常是什么。

根据我的经验,当你没有得到堆栈跟踪时,这意味着你正在双重释放。僵尸是找到你的双重释放的方式。

转到:产品 ->配置文件,然后从列表中选择“僵尸”。
运行应用程序并执行导致崩溃的任何任务,如果问题是双重释放,则会出现弹出窗口。选择弹出窗口中的箭头,它会准确告诉您正在双重释放的对象,并显示保留周期。

We can't really help you without seeing the whole stack trace.
EXC_BAD_ACCESS doesn't mean anything in order to troubleshoot we need to know what the exception is.

Based on my experience when you don't get a stack tarce it means you are double releasing. Zombies is the way to find your double release.

Go to: Product -> Profile and then select "Zombies" from the list.
Run the app and perform any task that causes the crash, if the problem is a double release a pop-up would appear. Select the arrow in the popup and it tells you exactly what object is being double released, and it shows you the retain cycle.

毁梦 2025-01-12 19:54:31

如果您的问题中没有发布任何代码,并且看到您使用的是 iOS 5 和 Xcode 4.2,我对您的最佳建议是,在 Xcode 中,转到 Edit>Refactor>Convert to Objective-C ARC 并挥手告别所有令人头疼的内存管理问题。

ARC 为您完成所有内存管理。您不需要保留、释放或编写 dealloc 方法。大多数情况下您不必担心内存管理。您将留下神秘的 EXC_BAD_ACCESS 崩溃。它的工作方式非常高效。编译器会为你放入retain和release,然后进行优化。您甚至不必查看代码。

Without any code posted in your question, and seeing that you are using iOS 5 and Xcode 4.2 my best advice for you is, in Xcode, go to Edit>Refactor>Convert to Objective-C ARC and wave all your memory management headaches goodbye.

ARC does all the memory management for you. You do not need to retain, release or write dealloc methods. You don't have to worry about memory management in most cases. You will leave mysterious EXC_BAD_ACCESS crashes behind. The way it works is super efficient. The compiler puts in the retains and releases for you and then optimises. You never even have to see the code.

橘和柠 2025-01-12 19:54:31

啊天啊我不相信这个。

之前堆栈分配的 NSInteger 变量所面临的问题仍然存在,但在这种情况下,这完全是我的错。

“doSomething”是一长串事件的一部分,由于我的一些愚蠢的疏忽,最终循环了很多次,这就是正确且应该的,导致应用程序内存不足的原因。无论是使用堆栈变量还是使用堆上的 malloc 变量,如果存在无限循环,它都会以某种方式崩溃。 :)

所以这次崩溃是完全公平的,只是在这种情况下与之前的一个无关的问题混淆了。 :(

抱歉浪费了大家的时间。

Ah geez I don't believe this.

The issues faced earlier with the stack-allocated NSInteger variables holds, but in this case, it was entirely my fault.

"doSomething" was part of a long chain of events, that, due to some silly negligence on my part, ends up looping a bunch of times, which is what, rightfully and as it should be, leads to the application running out of memory. Whether it's with the stack variables or with the malloced ones sitting on the heap, with an infinite loop, it's gonna crash one way or another. :)

So the crash is perfectly fair, just got confused in this case with a previous issue that turned out to be unrelated. :(

Sorry for wasting everybody's time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文