objective-c iPhone 开发:被释放的指针未分配
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1424210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iPhone development: pointer being freed was not allocated
提问by w4nderlust
i got this message from the debugger:
我从调试器收到这条消息:
Pixture(1257,0xa0610500) malloc: *** error for object 0x21a8000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
so i did a bit of tracing and got:
所以我做了一些追踪并得到:
(gdb) shell malloc_history 1257 0x21a8000
ALLOC 0x2196a00-0x21a89ff [size=73728]: thread_a0610500 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopDoObservers | CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) | CA::Transaction::commit() | CA::Context::commit_transaction(CA::Transaction*) | CALayerDisplayIfNeeded | -[CALayer _display] | CABackingStoreUpdate | backing_callback(CGContext*, void*) | -[CALayer drawInContext:] | -[UIView(CALayerDelegate) drawLayer:inContext:] | -[AvatarView drawRect:] | -[AvatarView overlayPNG:] | +[UIImageUtility createMaskOf:] | UIGraphicsGetImageFromCurrentImageContext | CGBitmapContextCreateImage | create_bitmap_data_provider | malloc | malloc_zone_malloc
(gdb) shell malloc_history 1257 0x21a8000
ALLOC 0x2196a00-0x21a89ff [size=73728]: thread_a0610500 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopDoObservers | CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) | CA::Transaction::commit() | CA::Context::commit_transaction(CA::Transaction*) | CALayerDisplayIfNeeded | -[CALayer _display] | CABackingStoreUpdate | backing_callback(CGContext*, void*) | -[CALayer drawInContext:] | -[UIView(CALayerDelegate) drawLayer:inContext:] | -[AvatarView drawRect:] | -[AvatarView overlayPNG:] | +[UIImageUtility createMaskOf:] | UIGraphicsGetImageFromCurrentImageContext | CGBitmapContextCreateImage | create_bitmap_data_provider | malloc | malloc_zone_malloc
and i really can't understand what i am doing wrong. here's the code of the [UIImageUtility createMaskOf:]function:
我真的不明白我做错了什么。这是[UIImageUtility createMaskOf:]函数的代码:
+ (UIImage *)createMaskOf:(UIImage *)source {
CGRect rect = CGRectMake(0, 0, source.size.width, source.size.height);
UIGraphicsBeginImageContext(CGSizeMake(source.size.width, source.size.height));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, source.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
UIImage *original = [self createGrayCopy:source];
CGContextRef context2 = CGBitmapContextCreate(NULL, source.size.width, source.size.height, 8, 4 * source.size.width,
CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipLast);
CGContextDrawImage(context2, CGRectMake(0, 0, source.size.width, source.size.height), original.CGImage);
CGImageRef unmasked = CGBitmapContextCreateImage(context2);
const float myMaskingColorsFrameColor[6] = { 1,256,1,256,1,256 };
CGImageRef mask = CGImageCreateWithMaskingColors(unmasked, myMaskingColorsFrameColor);
CGContextSetRGBFillColor (context, 256,256,256, 1);
CGContextFillRect(context, rect);
CGContextDrawImage(context, rect, mask);
UIImage *whiteMasked = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return whiteMasked;
}
the other custom function called before that is the following:
在此之前调用的另一个自定义函数如下:
- (UIImage *)overlayPNG:(SinglePart *)sp {
NSLog([sp description]);
// Rect and context setup
CGRect rect = CGRectMake(0, 0, sp.image.size.width, sp.image.size.height);
NSLog(@"%f x %f", sp.image.size.width, sp.image.size.height);
// Create an image of a color filled rectangle
UIImage *baseColor = nil;
if (sp.hasOwnColor) {
baseColor = [UIImageUtility imageWithRect:rect ofColor:sp.color];
} else {
SinglePart *facePart = [editingAvatar.face.partList objectAtIndex:0];
baseColor = [UIImageUtility imageWithRect:rect ofColor:facePart.color];
}
// Crete the mask of the layer
UIImage *mask = [UIImageUtility createMaskOf:sp.image];
mask = [UIImageUtility createGrayCopy:mask];
// Create a new context for merging the overlay and a mask of the layer
UIGraphicsBeginImageContext(CGSizeMake(sp.image.size.width, sp.image.size.height));
CGContextRef context2 = UIGraphicsGetCurrentContext();
// Adjust the coordinate system so that the origin
// is in the lower left corner of the view and the
// y axis points up
CGContextTranslateCTM(context2, 0, sp.image.size.height);
CGContextScaleCTM(context2, 1.0, -1.0);
// Create masked overlay color layer
CGImageRef MaskedImage = CGImageCreateWithMask (baseColor.CGImage, mask.CGImage);
// Draw the base color layer
CGContextDrawImage(context2, rect, MaskedImage);
// Get the result of the masking
UIImage* overlayMasked = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext(CGSizeMake(sp.image.size.width, sp.image.size.height));
CGContextRef context = UIGraphicsGetCurrentContext();
// Adjust the coordinate system so that the origin
// is in the lower left corner of the view and the
// y axis points up
CGContextTranslateCTM(context, 0, sp.image.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Get the result of the blending of the masked overlay and the base image
CGContextDrawImage(context, rect, overlayMasked.CGImage);
// Set the blend mode for the next drawn image
CGContextSetBlendMode(context, kCGBlendModeOverlay);
// Component image drawn
CGContextDrawImage(context, rect, sp.image.CGImage);
UIImage* blendedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(MaskedImage);
return blendedImage;
}
回答by nevan king
I've had the same problem, with a lot of the same symptoms:
我遇到了同样的问题,有很多相同的症状:
- pointer being freed was not allocated error
- upgraded to Xcode 3.2
- error happening in code for images
- 被释放的指针未分配错误
- 升级到 Xcode 3.2
- 图像代码中发生错误
If I change the build target to 3.1, the errors in the simulator go away. If I run the code on the device, the errors don't appear. Possibly a bug in 3.0
如果我将构建目标更改为 3.1,模拟器中的错误就会消失。如果我在设备上运行代码,则不会出现错误。可能是 3.0 中的错误
My advice is to test with 3.1 as your target, and if you want, you can build for 3.0 for release and not worry about the errors as they don't happen on the device.
我的建议是将 3.1 作为您的目标进行测试,如果您愿意,您可以构建 3.0 以进行发布,而不必担心错误,因为它们不会发生在设备上。
回答by Tyler
It looks like you have a corrupted memory bug, and it is probably not in this code. Corrupted memory bugs are my second most-fun bugs, partially because they are often non-deterministic, and the symptoms (aka the crashes) usually happen long afterthe actual bug hit.
看起来您的内存错误已损坏,并且可能不在此代码中。损坏的内存错误是我第二个最有趣的错误,部分原因是它们通常是不确定的,并且症状(也就是崩溃)通常在实际发生错误后很久才发生。
There are two main types of memory bugs:
有两种主要类型的内存错误:
- Allocating more than you free.
- Freeing more than you allocate.
- 分配比你免费的多。
- 释放的比分配的多。
In this case it looks like you're freeing too much, which is the easier case to see (b/c it can crash earlier) but the harder to track down.
在这种情况下,看起来你释放了太多,这是更容易看到的情况(b/c 它可以更早地崩溃)但更难追踪。
Here is a strategy you can use to help find an extra deallocations:
这是您可以用来帮助查找额外释放的策略:
- Turn off some of your deallocations.
- See if the crash still occurs.
- 关闭一些释放。
- 查看是否仍然发生崩溃。
Ideally, you can find one single deallocation command which, when removed, will allow your code to work correctly. It might be useful to try a binary search approach, if that is practical for your codebase. If it's a large codebase, hopefully you're using version control and you can try to focus on the recent diff's.
理想情况下,您可以找到一个单独的解除分配命令,当删除该命令时,您的代码可以正常工作。如果对您的代码库实用,尝试二进制搜索方法可能会很有用。如果它是一个大型代码库,希望您正在使用版本控制,并且您可以尝试关注最近的差异。
Keep in mind that deallocations can be invoked in several different ways here. Most likely, you're calling releaseand autoreleaseon objects. It's also possible you might be explicitly calling dealloc(which is usually a mistake, though). And of course you might even be explicitly calling freedirectly.
请记住,这里可以通过几种不同的方式调用解除分配。最有可能的是,您正在调用release和autorelease对象。您也有可能明确调用dealloc(尽管这通常是错误的)。当然,您甚至可能free直接直接调用。
Once you've gotten rid of the extra deallocations, it's a good idea to also check for memory leaks (aka extra allocations). You can do this by using Instruments and other tools. A good place to start is by reading Finding Memory Leaksin the iPhone development guide.
一旦你摆脱了额外的释放,最好也检查内存泄漏(也就是额外的分配)。您可以使用 Instruments 和其他工具来做到这一点。一个好的起点是阅读iPhone 开发指南中的Find Memory Leaks。
Added:It's also a good idea to set a pointer to nilright after you've released it and are done using it. This way, if you call [objectPtr release];later, it won't do anything.
补充:nil在你释放它并完成使用它之后设置一个指针也是一个好主意。这样,如果您[objectPtr release];稍后再调用,它就不会执行任何操作。
(PS Btw, my #1 most-fun bug type is memory corruption in mutlithreaded code. I had one of those once in a multi-million line code base.)
(顺便说一句,我的#1 最有趣的错误类型是多线程代码中的内存损坏。我曾经在数百万行代码库中遇到过这样的错误。)
回答by Brad Larson
While probably not the cause of your crash, you are leaking memory by not releasing the context2, unmasked, and maskCore Foundation objects using CFRelease(), CFImageRelease(), or the like.
虽然你的崩溃的可能不是原因,你是不是释放泄漏内存context2,unmasked以及mask核心基础对象使用CFRelease(),CFImageRelease()或等。
回答by infiniteloop
I had the same issue with the following code.
我对以下代码有同样的问题。
-(void)adjustImageToImageView:(UIImage*)img{
float numPixels = 100;
float radius = 5;
UIGraphicsBeginImageContext(CGSizeMake(numPixels, numPixels));
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextBeginPath(c);
CGContextMoveToPoint (c, numPixels, numPixels/2);
CGContextAddArcToPoint(c, numPixels, numPixels, numPixels/2, numPixels, radius);
CGContextAddArcToPoint(c, 0, numPixels, 0, numPixels/2, radius);
CGContextAddArcToPoint(c, 0, 0, numPixels/2, 0, radius);
CGContextAddArcToPoint(c, numPixels, 0, numPixels, numPixels/2, radius);
CGContextClosePath(c);
CGContextClip(c);
[img drawAtPoint:CGPointZero];
UIImage *converted = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.imageView.image = converted; }
I took the function from the open source Twitterfon app.
我从开源 Twitterfon 应用程序中获取了该功能。
When I was trying to fix the issue, I tried changing the last line to
当我试图解决这个问题时,我尝试将最后一行更改为
self.imageView.image = [converted retain]
And that stopped the error messages in the console. I'm going to check this in Leaks soon to see whats happening.
这停止了控制台中的错误消息。我很快就会在 Leaks 中检查一下,看看发生了什么。
回答by mracoker
I just wanted to confirm, again, that I had was getting:
我只是想再次确认,我得到了:
pointer being freed was not allocated
被释放的指针没有被分配
error and it went away if i change my target os to 3.1 as opposed to 3.0
错误,如果我将目标操作系统更改为 3.1 而不是 3.0,它就会消失
回答by Ephraim
I've struggled with the same error in my code. What I was puzzled by is that my app worked in OS 3.0 without any problem until I made a minor modification to a code that has nothing to do with the CGImage* stuff. But once it started to fail, then it never worked without crashing. When I switched to 3.1, everything worked again. I narrowed down the error to a CGImageRelease() call. Either removing that line or adding a retain on the resulting UIImage resolved the problem--although this is a no solution since the app will be leaking memory.
我在我的代码中遇到了同样的错误。让我感到困惑的是,我的应用程序在 OS 3.0 中运行没有任何问题,直到我对与 CGImage* 内容无关的代码进行了小幅修改。但是一旦它开始失败,它就不会在不崩溃的情况下工作。当我切换到 3.1 时,一切又恢复了。我将错误范围缩小到 CGImageRelease() 调用。删除该行或在生成的 UIImage 上添加保留解决了问题——尽管这不是解决方案,因为应用程序将泄漏内存。
I tried using NSZombie with instruments. This didn't help--the app crashed without any zombies being detected.
我尝试将 NSZombie 与乐器一起使用。这没有帮助——应用程序在没有检测到任何僵尸的情况下崩溃了。
Furthermore, Apple's own example apps (like TheElements) does NOT crash but uses the same EXACT code as my app. So, I'm struggling to accept the problem lies in the Frameworks. For now, I am switching to 3.1 and moving on.
此外,Apple 自己的示例应用程序(如 TheElements)不会崩溃,而是使用与我的应用程序相同的 EXACT 代码。所以,我很难接受问题出在框架中。现在,我正在切换到 3.1 并继续前进。
回答by dkardell
It might be just me but you can't do the following ?
可能只有我,但您不能执行以下操作?
UIImage *whiteMasked = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return whiteMasked;
whiteMasked is allocated on the stack of the function and after it returns the pointer is no longer valid? Or am I missing something? If you use the returned UIImage* it is not guaranteed to still be there. (it would be a hit and miss). Don't you need to alloc a UIImage* and then autorelease it before returning?
whiteMasked 分配在函数的堆栈上,返回后指针不再有效?或者我错过了什么?如果您使用返回的 UIImage*,则不能保证它仍然存在。(这将是一个打击和错过)。你不需要分配一个 UIImage* 然后在返回之前自动释放它吗?

