我想了解下面的程序。执行时遇到错误,如下所示。
#include<iostream>
using namespace std;
class Base
{
public:
int *a;
int a1;
int b;
Base(){
cout<<"Inside Constructor"<<endl;
a1 = 10;
a = &a1;
cout<<" "<<a<<endl;
b = 20;
}
Base(const Base &rhs)
{
cout<<"Inside Copy Constructor"<<endl;
a = new int;
*a = *(rhs.a);
b = rhs.b;
}
~Base(void)
{
cout<<"Inside destructor"<<endl;
delete a;
}
};
int main()
{
Base obj;
Base obj2(obj);
cout<<"obj a "<<*(obj.a)<<" b "<<obj.b<<endl;
cout<<"obj2 a "<<*(obj2.a)<<" b "<<obj2.b<<endl;
obj.a1 = 30;
obj.b = 40;
cout<<"obj a "<<*(obj.a)<<" b "<<obj.b<<endl;
cout<<"obj2 a "<<*(obj2.a)<<" b "<<obj2.b<<endl;
return 0;
}
执行此代码时,我得到以下输出
Inside Constructor
Inside Copy Constructor
obj a 10 b 20
obj2 a 10 b 20
obj a 30 b 40
obj2 a 10 b 20
Inside destructor
Inside destructor
Segmentation fault
[编辑] 我一直在寻找一种方法来破坏我在拷贝构造函数中创建的堆内存。那么这里可以做些什么呢?请建议
[编辑]
答案 0 :(得分:1)
delete应该在使用new only的堆分配的内存上使用。
a1 = 10;
a = &a1;
在你的情况下&#34; a&#34;正在堆栈中保存内存的地址。所以,你不应该在那个记忆中调用删除。
答案 1 :(得分:0)
您必须删除使用new
(动态分配)获取的内存,而不是删除自动存储变量。
答案 2 :(得分:0)
在复制构造函数中,您使用 new operator 为指针 a 分配内存,因此您可以将其删除。但是因为您没有使用 new运算符在默认构造函数中,您可以删除指针 a 。 您必须使用delete opearator来释放堆中不在堆栈中的变量的内存。
当您使用 new operator 时,变量在堆中创建,其中在堆栈内存中创建局部变量,但不能使用删除运算符
删除答案 3 :(得分:0)
问题不在于复制构造函数,问题是你不能一直使用new
(如果你使用移动那么也许你会有一个观点)。你有一些选择。我想要有用,而不是详尽无遗,也许我错过了其他好的设计理念。
new
您可以在所有构造函数中添加一个new,因此析构函数始终可以调用delete
。即使你不需要它。这可能是一个丑陋的黑客,但是是一致的。
new
如果您从未使用过new
,则也不要使用delete
,编译器会确保一致性并确保您不会陷入困境。通常,您可以依赖构造函数上的编译器默认行为。
如果不是手动调用delete
而是将变量保存在unique_ptr
内,那么编译器会自动在析构函数中释放它。智能指针非常智能,可以知道它是否已初始化。
请注意,使用智能指针意味着您永远不应该调用delete
,因为如果您这样做而没有警告智能指针,您将遇到同样的问题。如果您不熟悉它们并且使用的是C ++ 11,那么学习它是一件好事:)
我不会保证这一点。它似乎非常C
而非C++
。但是,您始终可以跟踪bool
值并在销毁时检查它。这就像使用智能指针一样,但内部实现。我认为这是一个糟糕的设计理念,虽然在某些情况下具有教育意义。