gpt4 book ai didi

c++ - 为什么从方法返回时局部变量中的数据会损坏?

转载 作者:行者123 更新时间:2023-11-30 02:33:24 27 4
gpt4 key购买 nike

在测试我的 C++11 代码时,我遇到了一个我不清楚其来源的错误。我已经成功地在以下设计的程序中重现了该错误。

#include <iostream>

class Vector {
public:
double* data;
Vector(int n) {data = new double[n];};
~Vector() {delete[] data;}
};

Vector someMethod() {
if (true) {
Vector mat {3};
if (true) {
mat.data[0] = 0.1;
mat.data[1] = 0.2;
mat.data[2] = 0.3;
}
return mat;
}
}

int main() {
Vector mat { someMethod() };
std::cout << mat.data[0] << std::endl;
std::cout << mat.data[1] << std::endl;
std::cout << mat.data[2] << std::endl;
return 0;

}

程序产生以下输出:

0
0.2
0.3
*** Error in `./testy': double free or corruption (fasttop): 0x0000000001f75010 ***
Aborted (core dumped)

而输出应该是:

0.1
0.2
0.3

第一个值似乎已损坏。我尝试了不同的 Vector 长度,总是只有第一个值被破坏。我未能对上述行为提出令人满意的解释。我怀疑这是由于 Vector 对象是在 if() 语句的 block 范围内声明和初始化的,该语句位于 的 block 范围内一些方法()。但是我不明白为什么这应该是一个问题,如果确实是的话。


编辑

两种解决方案都有效,第一个遵循 3/5 规则,第二个遵循 0 规则。谢谢你!但是我仍然对为什么会出现这种行为感到困惑。什么机制导致值(value)被破坏?当我在 main 方法开始定义 Vector 对象时调用默认移动构造函数时,其默认实现中的什么原因导致此行为?

最佳答案

someMethod 生成Vector mat。此 Vector 被复制到 main 内的 Vector mat。由于您没有指定复制构造函数,编译器会为您提供默认的复制构造函数,它只复制 Vector 具有的每个元素,即 double * data。复制后,两个 Vector 都有一个指针指向相同的数据。然后 someMethod 中的原始 mat 被销毁,这意味着它的析构函数运行,删除了 both vector 的数据。一旦 someMethod 返回,您将得到一个带有无效 data 指针的 Vector mat。然后打印出无效内存,导致未定义的行为。在这种特殊情况下,未定义的行为决定为您提供稍微错误的输出,但它也很容易导致段错误。

我希望现在已经清楚为什么来自 zenith 的修复解决了这个问题。

关于c++ - 为什么从方法返回时局部变量中的数据会损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35524127/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com