【问题标题】:My allocated memory is beeing written to我分配的内存正在写入
【发布时间】:2010-09-01 14:22:38
【问题描述】:

我正在用 Objective-C 编写一个项目,但由于涉及到 OpenGL,所以我非常依赖普通的旧 C。

我有一个数据块,我通过以下方式从文件中读取到内存:

NSString *path = [[NSBundle mainBundle] pathForResource:@"iPadTest" ofType:@""];
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
data = [file readDataToEndOfFile];
currentImage = [ReadDataFiles getOrganizedImageData:data];

最后一个函数为我提供了一个结构,其中数据更易于访问,但仍然存在三个冗长的图像数据数据块。开头是这样的:

ImageData *organizedImageData = malloc(sizeof(ImageData));

// IMAGE DIMENSIONS
UInt64 *rawData = (UInt64 *) data.bytes;
organizedImageData->imageDimensions.x = *rawData;
rawData++;
organizedImageData->imageDimensions.y = *rawData;
rawData++;
organizedImageData->imageDimensions.z = *rawData;

// IMAGE 1
rawData++;
organizedImageData->image1Data = (UInt8*)rawData;
// IMAGE 2
rawData++;
organizedImageData->image2Data = (UInt8*)rawData;

// etc...

问题在于,当数据到达 OpenGL 函数时,其他内容已写入同一内​​存。结果每次都不一样,但数据永远不会持久。

当我告诉调试器在更改这些地址时暂停时,我最终会得到我无法做出任何事情的汇编代码。

我应该如何以及在哪里分配内存空间,以便程序的其余部分不会被它欺骗?

【问题讨论】:

  • 调试器在调用堆栈上显示什么?这给你一个线索吗?
  • 你能说出ImageData的结构是什么样的吗?

标签: objective-c c memory memory-management


【解决方案1】:

问题在于您不拥有名为 data 的变量,并且几乎可以肯定,当您第一次遇到自动释放池耗尽时,它会被释放(或者如果您使用 GC,它会在超出范围后消失)。当data 消失时,所有您精心创建的指向[data bytes] 的指针都会悬空。

在引用计数环境中,您需要在自动释放池耗尽之前将-retain 发送到data(保证在您返回运行循环时会发生),然后您需要在释放它时释放它完成其中的数据。在 GC 环境中,您只需要保留一个强引用,例如使其成为某个对象的 ivar。

或者,您可以将数据复制到其他地方,而不仅仅是创建指向数据位的指针。

【讨论】:

    【解决方案2】:

    抱歉,我还不能发布 cmets,所以这里有一个完整的答案:
    就像 jeremy 说的,你不拥有对 data 的引用,所以它会消失!

    但是,有几种方法可以确保它的可行性:

    1. data(我的意思是这里的指针!)存储在您的结构中,这样您就可以在使用完毕后释放它。
      如果您在 GC 下运行,请将该字段定义为 __strong void * 或(因为 NSData 已免费桥接到 CFData)调用 CFRetain( (CFDataRef) data ) 其中 is actually not a noop in GC-ed code! (顺便说一句,这已经涵盖了 GC-ed ref-counted 环境...)
    2. 通过[[NSData alloc] initWithContentsOfFile:] 创建该对象并将其存储到您的结构中。 (GC-notes 也适用于此!)
    3. malloc 图像的内存并使用 -[NSData getBytes:range:]
      不过,这可能意味着显着的性能下降。

    无论您选择哪种方式,都不要忘记自己清理——CFRelease() 可能是案例 1 和 2 中最好的解决方案,因为它涵盖了 GC 和引用计数。


    顺便说一句(我希望这不会显得粗鲁!):
    是不是有一定的原因...

    1. 您使用的是NSFileHandle,而不是直接通过NSData-methods?
    2. 您以这种方式将数据保存为 blob?
      您可以通过NSKeyedArchiver 将其存储为二进制plist,并比通过指针体操更优雅地检索它,而且开销很小。

    哦,还有大的:
    究竟你在做什么/想做什么:

    // IMAGE 1
    organizedImageData->image1Data = (UInt8 *)rawData;
    rawData++;
    // IMAGE 2
    organizedImageData->image2Data = (UInt8 *)rawData;
    rawData++;
    

    我无法理解这一点。
    顺便说一句,建议 2 也可能会简化这一点:-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-03
      • 2021-10-12
      • 2010-09-27
      • 2015-09-11
      相关资源
      最近更新 更多