- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
下面的代码运行良好。但是,当我在 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;
在这些行之后会发生的是 a1
的 p
成员将被删除两次,从而导致更多未定义的行为。罪魁祸首是 automatically generated copy assignment operator ,它只是按值将 p
从 a1
复制到 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/
我在从 python 调用共享 c 库时遇到问题。库加载正常,公开的 3 个函数之一是可调用的,并且按预期工作;但是,当向库中添加另一个函数时,我发现其他两个不起作用。发生的事情是 python 卡在
我在使用 ImageIcon().GetImage() 时遇到问题 奇怪的是,它有时可以工作并向我显示带有 map 的窗口,而有时却不能。它也可以在其他计算机上完美运行,但不能在我的计算机上运行! 我
我们有时会遇到一个问题,即我们在 IIS 中有许多具有以下状态的请求:RequestAcquireState。 我们正在使用 SqlSessionStateStore 来管理 session 。当我们
我有一个 MobileSubstrate 插件,可以挂接跳板(不在实际的 objective-c 代码中,而是在 plist 中)。它包含一个 UIWebView,它加载一个 NSURLRequest
我正在尝试使用 Django 1.7,并按照说明进行操作 here .不幸的是,该过程似乎因以下输出而挂起: [Watt] ~/Projects/proj/proj master > python p
我正在使用 HDP 2.3.0.0-2557,我正在尝试运行如下所示的配置单元查询: beeline> !connect jdbc:hive2://localhost:10000 Connecting
我正在尝试使用 mxnet 设置 AWS Greengrass,以便在 Raspberry Pi 上进行机器学习。 当从 https://docs.aws.amazon.com/greengrass/
我是一名优秀的程序员,十分优秀!