我有一个类指针声明:
MyClass* a;
在销毁方法中我有:
if (a)
{
delete a;
a= NULL;
}
删除指针a时遇到问题:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
问题的原因是什么?如何摆脱它?
答案 0 :(得分:4)
根据您当前的声明:
MyClass* a;
a
获取随机值。如果您以后再也没有给它一个有效值,例如:
a = new MyClass();
它将指向内存中的未知位置,很可能不是为您的程序保留的内存区域,因此当您尝试删除它时会出现错误。
避免此问题的最简单方法是在声明时为a
提供值:
MyClass* a = new MyClass();
或者,如果你在声明它时不能给它一个值(也许你还不知道它),请将它指定为null:
MyClass* a = 0;
顺便说一句,您可以从代码中删除测试(if (a)
)。 delete
是空指针上的无操作。
答案 1 :(得分:2)
除非你在此之后初始化指向某事的指针:
MyClass* a;
指针a
将保留一些随机值。所以你的测试
if (a) { }
将通过,并尝试删除一些随机内存位置。
您可以通过初始化指针来避免这种情况:
MyClass* a = 0;
其他选项是指向的对象已在其他位置删除,指针未设置为0
,或者指向在堆栈上分配的对象。
正如其他地方所指出的那样,可以通过使用智能指针而不是首先使用裸指针来避免所有这些麻烦。我建议你看一下std::unique_ptr。
答案 2 :(得分:2)
使用智能指针释放内存。应用程序代码中的delete
总是错误的。
答案 3 :(得分:1)
你是如何分配a
指向的内存的?如果您使用new[]
(为了创建MyClass
数组),则必须使用delete[] a;
取消分配它。如果您使用malloc()
分配它(在使用类时可能不是一个坏主意),则必须使用free()
取消分配它。
如果您使用new
分配内存,则可能在其他位置发生了内存管理错误 - 例如,您可能已经解除分配a
,或者您已经编写了某些数组的边界之外。尝试使用Valgrind调试内存问题。
答案 4 :(得分:1)
你应该使用
MyClass* a = NULL;
在你的声明中。如果您从未实例化过,则指针指向未定义的内存区域。当包含类析构函数执行时,它会尝试delete
该随机位置。
答案 5 :(得分:1)
执行MyClass* a;
时,声明指针而不分配任何内存。您没有初始化它,a
不一定是NULL。因此,当您尝试删除它时,您的测试if (a)
会成功,但是重新分配失败。
如果可以使用C ++ 11,则应该MyClass* a = NULL;
或MyClass* a(nullptr);
。
(我假设在这种情况下你不会在任何地方使用new
,因为你告诉我们你只是声明一个指针。)