以下代码真的很危险吗? doSmth返回vector的对象,该对象应从cont
(doSmth
)复制,然后存储在函数test
范围内的堆栈中。因此,我相信只有在从test
返回后它才会被解构。
struct MyData
{
double m_i;
};
std::vector<MyData> doSmth()
{
std::vector<MyData> cont(10);
return cont;
}
void test()
{
MyData& oneElement = doSmth()[0];
std::cout << oneElement.m_i << std::endl;
}
然而valgrind的想法不同:
Invalid read of size 8
<line 1 in test function oneElement>
Address 0x101281db8 is 8 bytes inside a block of size 72 free'd
std::vector<BlockInfo, std::allocator<BlockInfo> >::~vector() (stl_vector.h:314)
<line 2 in test function>
这是我的逻辑或valgrind谎言中的问题吗?
答案 0 :(得分:4)
返回值在完整表达式结束时被销毁,即在函数test
的第一个分号处被销毁。此时,oneElement
成为悬空参考。
您可以通过将返回值绑定到const引用来延长返回值的生命周期:
void test()
{
std::vector<MyData> const & r = doSmth();
MyData const & oneElement = r[0];
std::cout << oneElement.m_i << std::endl;
}
在上面的例子中,返回值在函数结束时被销毁。
答案 1 :(得分:2)
代码具有未定义的行为。 doSmth
的返回值为a
临时的,在完整表达结束时被破坏。您
在其上调用operator[]
,它返回对数据内部的数据的引用
临时。破坏后的临时,参考
悬挂,任何使用都是不确定的行为。
Valgrind抱怨是对的。