gpt4 book ai didi

c++ - 为什么析构函数挂了

转载 作者:行者123 更新时间:2023-11-30 03:21:08 25 4
gpt4 key购买 nike

下面的代码运行良好。但是,当我在 GetValue 中启用 p=&b 时,代码失败“Debug Assertion Failed”。为什么?

class A{
int *p;
public:
A(){p=nullptr;}
~A(){if(p!=nullptr)delete p;}
void GetValue(int b);
};

void A::GetValue(int b){
*p=b;
//p=&b; this will cause destructor to hang, why?
}

int main(void){
A B;
B.GetValue(5);
}

最佳答案

首先,重要的是您只能删除 使用new 分配的内存。当前,您的类 A 存储了一个指针 p,它不是使用 new 分配的,但是您确实 delete p就好像它曾经是。这样做的结果是未定义的行为,这意味着您的程序不能保证正确运行,并且应该预料到非常奇怪的错误。

其次,在函数A::GetValue(int b);中,参数b是一个临时变量。调用 GetValue 时,会在调用堆栈上创建一些空间来传递 b 的值,该值在函数的生命周期内驻留在那里。但在 GetValue 返回后,b 不再存在 那里。虽然 C++ 允许您存储指向无效内存的指针,但您需要小心避免使用此类指针。

要使您的类 A 正常工作,需要进行一些修改,但我会边做边解释。虽然目前将 int* 指针存储在一个简单的 int 成员可以做的地方似乎没有多大意义,但我会继续使用该指针来帮助您理解,并让原始指针的管理成为一项学习练习。


大部分问题源于A::GetValue(int)。在这里,您正在存储一个临时变量的地址,并且在一个需要 new 指针的上下文中。相反,您应该确保正确分配内存,而不是存储指向 transient 参数 b 的指针:

A::GetValue(int b){
if (p == nullptr){
// if p is null, it needs to be allocated before being written to
p = new int(b); // initialize the memory at p to have value b
} else {
// otherwise, p has already been allocated, and its old value can be overwritten
*p = b;
}
}

当您编写以下代码时会出现另一个更微妙的问题:

A a1, a2;
a1.GetValue(13);
a2 = a1;

在这些行之后会发生的是 a1p 成员将被删除两次,从而导致更多未定义的行为。罪魁祸首是 automatically generated copy assignment operator ,它只是按值将 pa1 复制到 a2。要修复它,您需要编写自己的复制赋值运算符和复制构造函数,如下所示。复制构造函数有点复杂,因为要处理很多不同的情况。

class A {
...
A(const A& other) : p(nullptr) {
if (other.p){
p = new int(*other.p); // allocate new int and initialize with other's value
}
}
A& operator=(const A& other){
if (p){
// if this is managing a pointer
if (other.p){
// if other is managing a pointer too, just copy value
*p = *other.p;
} else {
// otherwise, since other is null, delete and make this null
delete p;
p = nullptr;
}
} else {
// if this is not managing a pointer
if (other.p){
// other is managing a pointer, time to allocate
p = new int(*other.p);
}
// nothing needs to be done if both are null
}
}

这样做的重要性在 Rule of Three 中有解释。 .

关于c++ - 为什么析构函数挂了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52306425/

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