正在破坏函数返回的堆栈上的对象
Destructing objects on stack returned from funciton
下面的代码真的很危险吗?doSmth返回向量的对象,该对象应从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>
这是我逻辑上的问题还是残酷的谎言?
返回值在完整表达式的末尾销毁,即函数test
中的第一个分号。在这一点上,oneElement
变成了一个悬空参考。
您可以通过将返回值绑定到常量引用来延长其生存期:
void test()
{
std::vector<MyData> const & r = doSmth();
MyData const & oneElement = r[0];
std::cout << oneElement.m_i << std::endl;
}
在上述情况下,返回值在函数结束时被销毁。
代码具有未定义的行为。doSmth
的返回值是temporary,它在完整表达式的末尾被销毁。你对其调用operator[]
,返回对短暂的临时销毁后,参考挂起,任何对它的使用都是未定义的行为。
Valgrind抱怨是对的。
相关文章:
- 作为指针注入类后重新创建堆栈对象不好吗?
- 堆分配对象中的堆栈对象在 c++ 中在哪里分配?
- 模板堆栈对象的数组;语法
- 有效地分配堆栈对象(由函数的值返回)到堆?
- 堆栈对象的强制转换指针
- 指向堆栈对象的指针是否在超出范围时被删除
- 重建堆栈对象
- 在执行中脱离堆栈对象的范围之前,请分配堆栈对象
- 堆栈对象"lost"会发生什么情况?
- 对 stl 堆栈对象大小的限制
- 堆栈对象"delete"的行为是什么?
- 为什么异常总是在具有可破坏堆栈对象的非叶函数中产生开销
- 是否可以为 CString 返回堆栈对象以及为什么 /GR 导致未定义的行为dynamic_cast
- 何时构造函数调用中的堆栈对象
- C++堆栈对象的构造函数异常处理
- 将没有成员的函子设置为类成员对象还是堆栈对象更有效
- 堆栈对象的动态强制转换失败
- 堆栈对象的最大大小
- 为什么我的堆栈对象在创建后会更改默认值
- 指向没有所有权的堆栈对象的指针