具有指定大小的自动释放 UIImages 的奇怪 malloc 错误

Posted

技术标签:

【中文标题】具有指定大小的自动释放 UIImages 的奇怪 malloc 错误【英文标题】:Strange malloc error with autoreleased UIImages of specified size 【发布时间】:2009-09-29 20:42:24 【问题描述】:

我正在追踪一个奇怪的错误。该错误通过在控制台日志中显示此消息来表现出来:

BlurApp(5018,0xa00d6500) malloc: *** error for object 0x103b000: pointer being freed was not allocated

执行离开我的事件循环后会弹出此消息。它似乎在自动释放池被耗尽时发生。这是似乎触发错误的代码:

- (UIImage*)imageWithImage:(UIImage*)image 
     scaledToSize:(CGSize)newSize;

 UIGraphicsBeginImageContext( newSize );
 [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
 UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();

 return newImage;

我这样调用 imageWithImage:

UIImage* theImage = [self imageWithImage:origImage scaledToSize:rect.size];

theImage 在调用例程中使用,然后我假设 autorelease 会处理它。

如果我将return newImage; 更改为返回[newImage retain];,则看不到错误消息。

现在,这很奇怪。此错误仅发生在某些大小的 newSize 中。具体来说,当 newSize 的高度和宽度等于 55 到 176 范围内的任何数字(不包括 56、110、112、114)时,它总是会发生,而不是在 5 到 300 之间的其他高度和宽度值。(高度和宽度是所有测试总是相等的)

我可以用新的眼光来看待这个...谢谢!

【问题讨论】:

这似乎是 Simulator 3.0 SDK 中的一个错误。我在模拟器的 SDK 3.1 中看不到这些错误消息,在 iPhone 上也看不到错误消息。 【参考方案1】:

尝试打印从 UIGraphicsGetImageFromCurrentImageContext 返回的图像的 retainCount。

类似:NSLog(@"Image retain count: %u", [newImage retainCount]);

或在代码上设置断点并在 gdb 控制台输入以下内容:

print (int) [newImage retainCount]

retainCount 应该大于零,可能是一。单步执行代码并继续检查 retainCount 以查看它何时达到零。

有一个类似的线程: iPhone development: pointer being freed was not allocated

【讨论】:

底部的链接指向一个类似的问题,这让我认为这是模拟器中的一个错误。我应该提到我在模拟器上运行它。我在 iPhone 上试用了该应用程序。那里没有错误。我还尝试使用 Simulator 3.1 SDK 而不是 3.0。 Simulator 3.1 下没有错误。【参考方案2】:

theImage 在调用例程中使用,然后我假设 autorelease 会处理它。

如果我改变返回 newImage;返回 [newImage 保留];看不到错误信息。

现在,这很奇怪。此错误仅发生在某些大小的 newSize 中。

在垃圾收集语言中,只要不再引用对象,垃圾收集器就可以清理(释放)对象。为了提高性能,垃圾收集可能会延迟——即直到有空闲时间、经过一定时间或内存条件达到某个阈值。

因此,一些对象可能会立即被释放,而另一些对象可能会在很久以后被释放或永远不会被释放(直到环境关闭)。

【讨论】:

这是给 iPhone 的,它没有垃圾回收功能。

以上是关于具有指定大小的自动释放 UIImages 的奇怪 malloc 错误的主要内容,如果未能解决你的问题,请参考以下文章

通过UIStackView在同等大小的UIImages下安排自定义大小的UILabels

当自动释放池耗尽时,NSFileAttributes dealloc 中的 SIGSEGV SEGV_ACCERR 崩溃?

详细说一下C#中using自动释放资源的用法

具有大量自动释放对象的线程如果是/否,在这种情况下是不是必须使用自动释放池,为啥?

具有自动布局约束的 UITableViewCell 子类大小不正确

释放对象时的奇怪行为