2015-11-05 185 views
4

考虑下面的C++代码。引用是否会导致内存泄漏?

struct foo { std::string value; } 

inline foo bar() { return { "42" }; } 

现在想象一下,我有一个函数使用bar()以下面的方式。

std::string my_func() 
{ 
    const auto &x = bar(); 
    return x.value; 
} 

这是否泄漏内存因为my_func只保存对x的引用?或者在my_func终止后x仍然清理干净?

我知道这不是应该如何使用引用。但我只是意识到这个编译好,并想知道它的语义是什么。

+3

这应该甚至编译?你不需要'const auto&'? – Brian

+0

你说得对。我有我的原始代码中的const auto。 –

回答

1

不,该字符串被复制到返回值中。函数之后,由x引用的对象超出了范围。

+2

这不应该编译 – Slava

+0

它为我编译gcc 5.2。那是令我困惑的。 –

+0

它编译和工作得很好。除了在struct foo {std :: string value; }' – pewpew

1

这不是泄漏,您的参考只是指向由堆栈展开清理的内存,这是由于临时内存引起的。目的。

访问x将导致未定义的行为。可能是访问冲突。

+0

我一直在我的项目中使用非常类似的代码行约一个月,没有任何问题。那是令我困惑的。 –

+0

@KaiMast:很难说为什么它在为你工作而不知道你的意思是什么。例如,当你返回一个静态变量的引用时,这对你很有用。 如果你想分享我们的代码片段,也许我们可以说更多为什么它为你工作。 –

+0

该引用并未指向已在此代码中的任何位置进行清理的内存。 – nos

6

But I just realized this compiles fine

提供的代码不应该编译,因为试图将临时指定给左值引用。

error: invalid initialization of non-const reference of type ‘foo&’ from an rvalue of type ‘foo’

如果你修复代码,由

std::string my_func() 
{ 
    const auto &x = bar(); 
    return x.value; 
} 

那么这将是罚款,作为常引用为常引用寿命延长的临时寿命。

+0

对不起......我有我的原始代码const。 –

3

简答题:没有。

较长的答案:在这种情况下,编译器将确保被引用的临时对象将活到当前作用域的末尾。 bar()按值返回n个对象。这将被复制到临时的匿名对象中,然后引用将引用该临时对象。

还有其他类似的情况,其中标准有这样一个明确的要求:绑定到引用的临时对象直到达到当前作用域的末尾。

相关问题