Objective c 结构内存分配(泄漏和崩溃,在iPhone上分析)

Objective c 结构内存分配(泄漏和崩溃,在iPhone上分析),objective-c,c,memory-management,struct,profiling,Objective C,C,Memory Management,Struct,Profiling,我将结构定义为: struct VImage { uint8_t *imageData; int dimensions[3]; ... } 我正在分析代码以查找漏洞和其他问题。考虑下面的代码: for (int i = 0; i < 100; i++) { // after we have the image, we use the cheap rgb function to get rgb data struct VImage *vImage =

我将结构定义为:

struct VImage
{
    uint8_t *imageData;
    int dimensions[3];
    ...
}
我正在分析代码以查找漏洞和其他问题。考虑下面的代码:

for (int i = 0; i < 100; i++)
{
    // after we have the image, we use the cheap rgb function to get rgb data
    struct VImage *vImage = [SomeClass someFunction:someArgument];
    free(vImage);
}

所以我所做的就是通过一些计算,使用rgb数据创建一个灰度图像。但是,我认为这里没有任何问题。

首先,您正在泄漏由
grayScaleImageData
指向的内存:

在grayScaleImageDataFromImage中,您可以

uint8_t *grayScaleImageData = (uint8_t *) malloc(imageWidth * imageHeight);
这很好,然后在
createGrayscaledDescription
中设置
vImage->grayScaleImage
指向该内存,这也很好

但是在1到100的循环中,您释放了vImage,而没有首先释放
vImage->grayScaleImage
指向的内存。这是内存泄漏

我不认为这会使您的应用程序崩溃,但这是您需要解决的问题。没有其他的东西向我扑来,但我会仔细看看

编辑:仔细检查,您似乎超出了分配的缓冲区
灰度图像数据

您可以通过以下方式来实现:

uint8_t *grayScaleImageData = (uint8_t *) malloc(imageWidth * imageHeight);
但随后,您将用以下内容填充该缓冲区:

uint32_t rgbPixel = rgbImageData[y*imageWidth+x];
grayScaleImageData[y*imageWidth + x] = 0.299*((rgbPixel>>24)&255) + 0.587*((rgbPixel>>16)&255) + 0.114*((rgbPixel>>8)&255);
您已分配(imageWidth*imageHeight)8位UINT,但随后将其填充为32位UINT

也许这就是导致你崩溃的原因?也许试着把那个malloc改成

uint32_t *grayScaleImageData = (uint32_t *) malloc(imageWidth * imageHeight * sizeof (uint32_t));
正如您在上面对rgbImageData所做的那样?或者在将位移位计算结果设置为灰度图像数据之前,将其转换为uint8\u t:

uint32_t rgbPixel = rgbImageData[y*imageWidth+x];
grayScaleImageData[y*imageWidth + x] = (uint8_t)(0.299*((rgbPixel>>24)&255) + 0.587*((rgbPixel>>16)&255) + 0.114*((rgbPixel>>8)&255));

这取决于
someFunction
的实现。你能分享它的代码吗?发布
someFunction:someArgument:
?@Zaph的代码。它与你提供的链接中的问题无关@Merlevede,我已经发布了
someFunction
的代码。所以在你回答这个问题之前,我做了更多的研究,并确切地了解了你在说什么。但是,我认为free(vImage)可以完成这项工作,但是在从方法返回
vImage
之前,我需要释放
grayScaleImage
指向的内存。这就是我现在的战斗方式。我不认为释放
vImage->grayScaleImage
是正确的做法。你能评论一下这是否是正确的方法吗?@flippex17:在你完成之前,你无法释放内存,所以不能。我编辑了我的答案,添加了我认为真正的问题。至于内存泄漏,您需要在释放(vImage)之前释放(vImage->grayScaleImage),因此grayScaleImageData不需要那么多信息。我不认为我正在溢出缓冲区,因为每次我运行它时它都会崩溃。我只输入以imageWidthimageHeight为上限的[yimageWidth+x]值。此外,这些移位和掩码都是8位;所以计算全部是8位。不过我会试试你的解决方案。@flippex17:只有最后一个超出了缓冲区,正好3个字节。位移位计算的结果是一个适合8位的数字,但它仍然是一个32位计算。最终结果是一个32位数字,其上24位为零。缓冲区溢出只有在覆盖重要内容时才会导致崩溃,所以它可能不会每次都崩溃。事实上确实如此。这将导致缓冲区溢出。我不想要32位的GrayscaleImage数据,所以我需要限制计算,使其仅为8位。不过,我很高兴失去一些信息。
uint32_t rgbPixel = rgbImageData[y*imageWidth+x];
grayScaleImageData[y*imageWidth + x] = (uint8_t)(0.299*((rgbPixel>>24)&255) + 0.587*((rgbPixel>>16)&255) + 0.114*((rgbPixel>>8)&255));