【问题标题】:Trouble spotting memory leak cStringUsingEncoding无法发现内存泄漏 cStringUsingEncoding
【发布时间】:2011-03-25 00:29:05
【问题描述】:

嘿,我正在尝试使用 cStringUsingEncoding 将 NSString 转换为 C 字符串,但我有内存泄漏。我的理解是 cStringUsingEncoding 返回一个指向字符数组的指针,该数组只保证在 NSString 对象的持续时间内存在。因此,您应该将其内容复制到另一个字符串。这就是我的问题所在......

我有一个接受 NSString 并将其转换为 C 字符串副本的函数。只是为了测试,我运行了以下方法的 1000 次迭代(以确保没有泄漏)。

 -(void)test{
      NSString *test = [[NSString alloc] initWithString:@"Hello world!"];

      for(int i=0; i<1000; i++)
      {
           char *tmp = [self returnCopiedCString:test];

           //free memory
           free(tmp);
      }

      [test release];
 }

相当直接的代码......问题是它会像疯了一样泄漏。现在,在您得出结论之前,我的 returnCopiedCString 函数工作得很好。我已经通过声明和复制一个 C 字符串来测试它,以排除这是一个问题的可能性。在函数内部我使用下面的代码来转换它

 -(char *)returnCopiedCString:(NSString *)input{
      //retain input
      [input retain];

      //get length of encoded C-string
      int len = [input lengthOfBytesUsingEncoding:NSUTF8StringEncoding];

      //allocate memory for new C-string + null terminated byte
      char *toReturn = (char *)malloc((sizeof(char) * len) +1);

      //copy NSString to C-string
      strcpy(toReturn,[input cStringUsingEncoding:NSUTF8StringEncoding]);

      //release input
      [input release];

      //return pointer to newly copied string
      return toReturn;
 }

也很简单。然后我开始好好思考,也许是因为我在 for 循环之外声明了 test,因此它永远不会被释放,我将所有这些 const char* 都留在 cStringUsingEncoding 方法中。所以我把第一个函数改成如下:

 -(void)test{
      for(int i=0; i<1000; i++)
      {
           NSString *test = [[NSString alloc] initWithString:@"Hello world!"];

           char *tmp = [self returnCopiedCString:test];

           //free memory
           [test release];
           free(tmp);
      }
 }

但仍然没有运气。有人对这里可能出现的问题有任何想法吗?提前致谢!

【问题讨论】:

  • 如果问题解决了,你应该接受解决它的答案,或者写一个描述解决方案的答案并接受它作为答案。

标签: c objective-c memory-leaks nsstring


【解决方案1】:

来自文档:

保证返回的 C 字符串仅在接收器被释放或当前自动释放池被清空之前有效,以先发生者为准。您应该复制 C 字符串或使用 getCString:maxLength:encoding: 如果超出此时间需要存储 C 字符串。

我认为 cStringUsingEncoding 正在为转换后的字符串分配内存以指定编码,并且您不保留接收器,因此如果您不使用自动释放池,则永远不会释放此内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    相关资源
    最近更新 更多