iPhone操作系统内存问题-如何调试?

iPhone操作系统内存问题-如何调试?,iphone,objective-c,memory,corruption,Iphone,Objective C,Memory,Corruption,我的iPhone应用程序中有一个非常奇怪的问题,我认为这与内存损坏有关: 在某一点上,我需要对数组进行排序,这是我使用-[sortarrayingfunction]完成的 结果是不正确的,除非我在方法调用之前分配一些内存,比如void*test=malloc(2*sizeof(int)),或者在排序函数中调用NSLog()(从未调用) 换句话说:只有在调用排序函数之前稍微增加内存,排序才会起作用。我想这是因为在某个时候,内存被破坏了 如何调试这样的东西?这样的事情可能是调试的挑战。在其他平台上,

我的iPhone应用程序中有一个非常奇怪的问题,我认为这与内存损坏有关:

在某一点上,我需要对数组进行排序,这是我使用
-[sortarrayingfunction]
完成的

结果是不正确的,除非我在方法调用之前分配一些内存,比如
void*test=malloc(2*sizeof(int))
,或者在排序函数中调用
NSLog()
(从未调用)

换句话说:只有在调用排序函数之前稍微增加内存,排序才会起作用。我想这是因为在某个时候,内存被破坏了


如何调试这样的东西?

这样的事情可能是调试的挑战。在其他平台上,有一些工具可以检测越界访问等,所以我认为iPhone会有一些东西,但我不知道有什么

也许您应该存储两个数组副本,并比较它们之间的差异。把差异打印出来。其中一个数组中引入的“垃圾”的性质可能会提示它来自何处


另外,只需浏览在这一点之前运行的代码,然后重新阅读(或者最好让其他人阅读)。您可能会发现一个bug。

听起来您的一些代码使用的是已经发布的对象。苹果公司的《伟大的技术笔记》中提供了大量调试此类错误的帮助,特别是其中的部分


对于您的情况,我将禁用自动释放池(设置环境变量
nsenableautoreasepool=NO
)或使用僵尸功能(
NSZombieEnabled=YES
)来查找向释放对象发送消息的位置。

尝试在Valgrind下的模拟器中运行您的程序:

以及如何在模拟器下使用它:


您可能必须根据安装位置更改代码示例中的VALGRIND路径。

当我设置NSEnableAutoreleasePool=NO时,问题似乎消失了。但是当设置NSZombieEnabled时,我没有收到任何消息,如果我没有将NSEnableAutoreleasePool设置为NO,但在main.m中将池设置为nil(这应该是等效的),问题仍然存在。。。一切仍然很奇怪,但自动释放可能是问题所在。好吧,现在你知道过度释放可能是问题所在。首先尝试静态分析器(叮当声)。然后,如果你没有发现问题,就开始观察可疑的物体并保留它们。如果问题消失了,你就知道哪个对象在它出现之前被释放了。B.t.w:当然,当启用僵尸检测时,你必须启用自动释放池。当问题第一次出现时,我尝试了叮当声,但没有用,它似乎认为我的代码很好。(我在运行之前也清理了项目。)当我删除项目中的所有发布调用时,问题似乎完全消失了,但当我重新启动应用程序时,我发现这只是暂时消失的症状。我现在很确定问题不在于过度释放或自动释放。但是在Obj-C代码中还有什么其他方法可以破坏内存呢?毕竟,有很多方法可以破坏它是C。但是,是什么确保这不是一个保留/发布问题呢?我假设您使用的是NSMutableArray sortUsingFunction:context:?你应该发布排序功能;如果您不知道我的应用程序的上下文(太复杂),发布排序功能将毫无帮助。我也不认为问题出在排序功能上,因为那样它总是会失败。