简体   繁体   中英

Program received signal EXC_BAD_ACCESS accessing array

I am using the routine for getting pixel colour (this one: http://www.markj.net/iphone-uiimage-pixel-color/ ) and am faced with frequent app crashes when using it. The relevant portion of the code:

unsigned char* data = CGBitmapContextGetData (cgctx);
if (data != NULL) {
    int offset = (some calculations here);
    int alpha = data[offset]; // <<<< crashes here
}

This code is linked to be ran on touchesBegan, touchesEnded and touchesMoved. It appears that the crashes occur during touchesEnded and touchesMoved events only, particularly when I start the touch on the target image, but move it off the boundaries of the image in the process.

Is there any way to check what is the size of the data in the array pointed to by data object? What could be going wrong there?

Edit : The calculation of offset:

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

Where point is the point where touch occurs, w is the width if the image, x is the scale of the image (for hi-res images on retina displays).

I don't see anything wrong with the cgctx either. Basically, I am running the code from the link above almost unmodified, the particular code snippet I have problems with is in the function (UIColor*) getPixelColorAtLocation:(CGPoint)point so if you want the details of what the code does, just read the source there.

Edit: another thing is that this never happens in the simulator, but often happens when testing on a device.

Edit: Ideally I'd want to do nothing if the finger is currently not over the image, but have trouble figuring out when that happens. It looks like the relevant methods in SDK only show what view the touch originated in, not where it is now. How can I figure that out?

You didn't show all your work. Your offset calculation is likely returning either a negative number or a number well beyond the end of the buffer. Since CG* APIs often allocate rather large chunks of memory, often memory mapped, it is quite likely that the addresses before and after the allocation are unallocated/unmapped and, thus, access outside of the buffer leads to an immediate crash (as opposed to returning garbage).

Which is good. Easier to debug.

You did provide a clue:

move it off the boundaries of the image in the process

I'd guess you modified the offset calculation to take the location of the touch. And that location has moved beyond the bounds of the image and, thus, leads to a nonsense offset and a subsequent crash.

Fix that, and your app will stop crashing here.


Does your image exactly occupy the entire bounds of the item being touched? Ie does the thing handling the touches*: events have a bounds whose width and height are exactly the same as the image?

If not, you need to make sure you are correctly translating the coordinates from whatever is handling the touches to coordinates within the image. Also note that the layout of bytes in an image is heavily dependent on exactly how the image was created and what internal color model it is using.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM