【问题标题】:Returning a pointer to memory allocated within a function返回指向函数内分配的内存的指针
【发布时间】:2010-09-30 18:08:32
【问题描述】:

在 C 语言中,类似以下的内容将是一场灾难(即内存泄漏),因为您返回了一个指向您永远无法释放的内存的指针:

NSString* foo()
{
  return [NSString stringWithFormat:@"%i+%i=%i", 2, 2, 2+2];
}

这实际上在 Objective-C 中完全没问题,因为返回的指针指向的内存将被自动释放?就算没问题,有什么理由不被人接受吗?有什么理由更喜欢 C 风格,如下所示?

void foo(NSString ** modifyMe)
{
  *modifyMe = [NSString stringWithFormat:@"%i+%i=%i", 2, 2, 2+2];
}

【问题讨论】:

  • 顺便说一句,您的第二个示例将失败。您不能在函数内部重新分配指针,因为指针本身是按值复制的。如果你想让你的第二个例子工作,你必须使用 NSString **modifyMe 作为参数...
  • 我通常将第二个示例中的模式称为“输出参数”。不知道其他人有没有,但我就是这么称呼的。

标签: objective-c cocoa memory memory-management memory-leaks


【解决方案1】:

Cocoa 中的函数与 Cocoa 中的所有其他函数遵循相同的内存管理规则。你的第一个例子很好。

【讨论】:

  • 谢谢克里斯!经过反思,这确实应该是显而易见的。但我想只有在你最终了解 Objective-C 中的内存管理时才会明白。所以也许这对人们来说是有价值的。尽管如此,我可能会因为尴尬而越来越想删除这个问题!
【解决方案2】:

这不仅在 Objective-C 中是可以的,而且在 C 中也不是问题,只要你有明确定义的所有权语义。

CFStringRef foo()
{
    return CFStringCreateWithFormat(NULL, CFSTR("%i+%i=%"), 2, 2, 2+2);
}

void bar()
{
    CFStringRef str = foo();
    CFRelease(str);
    // Nothing leaked.
}

【讨论】:

  • 不过,这不是对 Core Foundation 的正确使用,因为“foo”的名称不包含“Create”或“Copy”一词,以表明它交回了调用者必须的对象释放...
  • 非常正确,尽管我认为很少有人会建议“foo”在任何实际环境中都是一个好的函数名称……好吧,除了那些设计 C 标准库的白痴。 ;-)
  • 不能强调“创建”或“复制”的必要性。如果我不得不维护这样的代码,我会死的。
猜你喜欢
  • 1970-01-01
  • 2012-02-02
  • 2019-07-08
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多