被释放的指针没有被分配:iPhone开发(iPhone development: pointer b

2019-07-18 01:08发布

我从调试器这样的信息:

Pixture(1257,0xa0610500) malloc: *** error for object 0x21a8000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

所以我做了一些跟踪的,并得到:

(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

我真的不明白我在做什么错。 这里的的代码[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;
}

在此之前,所谓的其他自定义功能如下:

- (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;
}

Answer 1:

我有同样的问题,有很多相同的症状:

  • 指针被释放没有被分配错误
  • 升级到3.2的Xcode
  • 错误代码为发生图像

如果我改变了构建目标至3.1,在模拟器中的错误消失。 如果我在设备上运行的代码,错误不会出现。 可能在3.0中的错误

我的建议是3.1为目标进行测试,如果你愿意,你可以建立3.0版本,而不是担心,因为他们没有在设备上发生的错误。



Answer 2:

它看起来像你有一个损坏的内存错误,它可能不是在这个代码。 损坏的内存错误是我的第二个最有趣的错误,部分是因为他们往往不确定性,且症状(又名崩溃),通常实际的错误命中后不久发生。

主要有两种类型的内存错误的:

  1. 分配比你更自由。
  2. 释放比你分配更多。

在这种情况下,它看起来像你释放太多,这是比较容易看到的情况下(B / C能更早崩溃),但很难追查。

这里是一个战略,你可以用它来帮助找到一个额外的释放操作:

  • 关掉你的一些释放操作的。
  • 看看崩溃仍然存在。

理想情况下,你可以找到一个单一的释放命令,该命令,删除的时候,可以让你的代码才能正常工作。 这可能是有益的尝试二进制搜索方法,如果这是你的代码实用。 如果它是一个大的代码库,希望你正在使用的版本控制,你可以尝试把重点放在最近的差异的。

请记住,解除分配可在多种不同的方式在这里被调用。 最有可能的,你打电话releaseautorelease的对象。 也有可能,你可能会被显式调用dealloc (这通常是一个错误,虽然)。 当然,你甚至可能会显式调用free直接。

一旦你已经摆脱了多余的释放操作的,这是一个好主意,还检查内存泄漏(又名额外拨款)。 您可以通过使用工具和其他工具做到这一点。 一个良好的开始是通过阅读查找内存泄漏的iPhone开发指南。

补充:这也是一个指针设置为一个好主意, nil右您已经发布了它,使用它完成之后。 这样,如果你调用[objectPtr release]; 后来,它不会做任何事情。

(PS顺便说一句,我的#1最好玩的错误类型是mutlithreaded代码内存损坏。我有那些曾经在数百万行的代码库之一。)



Answer 3:

虽然你的崩溃的可能不是原因,你是不是释放泄漏内存context2unmasked ,并mask使用的Core Foundation对象CFRelease() CFImageRelease()等。



Answer 4:

我曾与下面的代码相同的问题。

-(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;   }

我从开源Twitterfon应用了该功能。

当我试图解决这个问题,我试图改变最后一行

self.imageView.image = [converted retain]

并且停在控制台中的错误消息。 我会在不久的泄漏检查这,看看发生了什么。



Answer 5:

我只是想确认,再次,我有是越来越:

指针被释放没有被分配

错误,如果我改变我的目标OS 3.1,而不是3.0它走了



Answer 6:

我一直挣扎在我的代码相同的错误。 我被困惑的是,我的应用程序在OS 3.0的工作没有任何问题,直到我做了一个小的修改有什么做的CGImage *的东西代码。 但是,一旦它开始失败了,那么它从来没有工作没有崩溃。 当我切换到3.1,再次一切工作。 我缩小了错误的CGImageRelease()调用。 或者除去该行或添加保留在所得的UIImage解决了这个问题 - 虽然这是一个没有解决方案,因为该应用将被泄漏内存。

我尝试使用NSZombie与仪器。 这并没有帮助 - 应用程序崩溃而不被发现的任何僵尸。

此外,苹果公司自己的例子Apps(例如TheElements)不会崩溃,但使用完全相同的代码,我的应用程序。 所以,我挣扎,接受问题出在框架。 现在,我切换到3.1,并继续前进。



Answer 7:

这可能只是我,但你不能做以下?

UIImage *whiteMasked = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return whiteMasked;

whiteMasked分配函数的栈和返回后的指针不再有效? 还是我失去了一些东西? 如果您使用返回的UIImage *它不能保证仍然存在。 (这将是一个命中和未命中)。 难道你需要的Alloc一个UIImage *,然后在返回前自动释放呢?



文章来源: iPhone development: pointer being freed was not allocated