【问题标题】:How memory leak can happen in this code此代码中如何发生内存泄漏
【发布时间】:2014-07-10 23:06:10
【问题描述】:

Here我看了一个会泄露内存的例子

void foo(std::shared_ptr<int> p, int init)
{
  *p = init;
}
foo(std::shared_ptr<int>(new int(42)), seed()); // assume seed() returns an int

文章说如果seed()抛出,那么就会出现内存泄漏。我不明白怎么做?

如果先创建shared_ptr,然后seed() 抛出异常,在堆栈展开期间,临时的shared-ptr 将被销毁,释放内存。如果seed()事先抛出错误,那么一开始就不会分配。

我错过了什么?

【问题讨论】:

  • 这将解释为什么 => herbsutter.com/gotw/_102
  • 简短回答:new int(42) 可以在 seed() 执行之前执行,并且在其结果绑定到函数参数之前执行。

标签: c++ memory-leaks shared-ptr


【解决方案1】:

执行顺序可以是

auto temp = new int(42);
auto temp2 = seed(); // if throw exception, temp is leaked
auto temp3 = std::shared_ptr<int>(temp);
foo(temp3, temp2);

【讨论】:

  • 您是说,在完全评估一个参数值之前,编译器可能会开始评估另一个?为什么呢?评价顺序难保证?或者至少一个会在另一个开始之前得到全面评估?
  • 只是因为标准确实指定了评估顺序
  • 如果编译器的指令调度程序在基本块的管道中发现漏洞,它会随机排列以填充它们,而不考虑表达式边界,只考虑数据依赖性。如果你依赖于函数参数的求值顺序,你就破坏了可维护性:维护者必须问的一个问题是“这个更改安全吗?”,从参数列表中提升参数计算通常是一件好事去做。如果 C++ 在此处允许依赖关系,则答案会从“是”变为“祝你好运”。既然如此,就没有理由阻碍优化器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-18
  • 2016-02-04
相关资源
最近更新 更多