unsigned char allocation在偏移值目标c中出现nils

时间:2014-02-17 06:54:44

标签: ios objective-c memory-leaks pixel unsigned-char

我从触摸点获取像素颜色值。我成功地做了这个,但有时app发出错误(EXC_BAD_ACCESS(CODE = 1,地址= 0x41f6864)。这里的内存分配问题是供你参考的源代码。

- (UIColor *) getPixelColorAtLocation:(CGPoint)point {
UIColor* color = nil;

@try{

    {

    CGImageRef inImage =  drawImage.image.CGImage;

// Create off screen bitmap context to draw the image into. Format ARGB is 4 bytes for each pixel: Alpa, Red, Green, Blue
CGContextRef cgctx = [self createARGBBitmapContextFromImage:inImage];
if (cgctx == NULL)
{
    return nil; /* error */

}  
size_t w = CGImageGetWidth(inImage);
size_t h = CGImageGetHeight(inImage);
CGRect rect = {{0,0},{w,h}};

// Draw the image to the bitmap context. Once we draw, the memory
// allocated for the context for rendering will then contain the
// raw image data in the specified color space.
   CGContextDrawImage (cgctx, rect, inImage);


// Now we can get a pointer to the image data associated with the bitmap
// context.
        unsigned char *data = {0};
       data=(unsigned char*) calloc(CGImageGetHeight(inImage) * CGImageGetWidth(inImage) , CGBitmapContextGetHeight(cgctx)*CGBitmapContextGetWidth(cgctx));

data= CGBitmapContextGetData (cgctx);






  if( data !=NULL  ) {



    //offset locates the pixel in the data from x,y.
    //4 for 4 bytes of data per pixel, w is width of one row of data.


      int offset = 4*((w*round(point.y))+round(point.x));

           // NSLog(@"%s111111",data);

     int alpha =  data[offset]; /////// EXC_BAD_ACCESS(CODE=1,address=0x41f6864)           

    int red = data[offset+1];
    int green = data[offset+2];
    int blue = data[offset+3];



    //NSLog(@"offset: %i colors: RGB A %i %i %i  %i",offset,red,green,blue,alpha);
     color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
    }
// When finished, release the context
//CGImageRelease(*data);
CGContextRelease(cgctx);

// Free image data memory for the context
if (data)
{

 free(data);  
}
}
@catch (NSException *exception) {
}
return color;
}

2 个答案:

答案 0 :(得分:1)

代码中的内存管理似乎有误:

声明data并毫无意义地为其指定一个值:

unsigned char *data = {0};

分配一个内存块并在data中存储对它的引用 - 覆盖无意义的初始化:

data = (unsigned char *)calloc(CGImageGetHeight(inImage) * CGImageGetWidth(inImage), CGBitmapContextGetHeight(cgctx) * CGBitmapContextGetWidth(cgctx));

现在获取对不同内存块的引用并将其存储在data中,丢弃对calloc'ed块的引用:

data = CGBitmapContextGetData (cgctx);

做一些其他的事情,然后释放你没有calloc的块:

free(data);

如果要分配自己的内存缓冲区,则应将其传递给CGBitmapContextCreate,但是如果您使用的是iOS 4+,则无需分配自己的缓冲区。

关于内存访问错误,您没有检查point的值,并且您的计算似乎产生的值offset不正确。添加对pointoffset的值的检查,如果超出界限则采取适当的措施(您必须确定应该是什么)。

HTH

答案 1 :(得分:0)

point超出图像rect可能导致问题,因此您可以使用

try{

    int offset = 4*((w*round(point.y))+round(point.x));
    int alpha =  data[offset];       
    int red = data[offset+1];
    int green = data[offset+2];
    int blue = data[offset+3];



    color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f)
         alpha:(alpha/255.0f)];

}catch(NSException e){

}

避免EXC_BAD_ACCESS