麻烦发现内存泄漏cStringUsingEncoding

时间:2010-08-04 00:07:36

标签: c objective-c memory-leaks nsstring

嘿,我正在尝试使用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循环之外声明测试,因此它永远不会被释放,我将从cStringUsingEncoding方法中留下所有这些const char *。所以我改变了第一个函数如下:

 -(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);
      }
 }

但仍然没有运气。有没有人对这里的问题有什么想法?提前一堆谢谢!

1 个答案:

答案 0 :(得分:3)

来自文档:

  

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

我认为cStringUsingEncoding正在为转换后的字符串分配内存为指定的编码,如果你没有使用自动释放池,你就不会保留接收器,所以永远不会释放这个内存。