我有以下代码,我得到堆栈溢出错误任何人都可以请解释我这里有什么问题。从我的理解,这个指针指向当前对象,所以为什么我不能在析构函数中删除它;
class Object
{
private:
static int objCount;
public:
int getCount()
{
int i =10;
return i++;
}
Object()
{
cout<< "Obj Created = "<<++objCount<<endl;
cout <<endl<<this->getCount()<<endl;
}
~Object()
{
cout<<"Destructor Called\n"<<"Deleted Obj="<<objCount--<<endl;
delete this;
}
};
int Object::objCount = 0;
int _tmain(int argc, _TCHAR* argv[])
{
{
Object obj1;
}
{
Object *obj2 = new Object();
}
getchar();
return 0;
}
答案 0 :(得分:15)
你在班级的析构函数中正在做delete this;
。
好吧,delete
调用了类的析构函数。
你在班级的析构函数中正在做delete this;
。
...
<!<!<!Stack Overflow!>!>!>
(对不起家伙,我觉得有必要把它包括在内......这可能会破坏它的悲伤性!
无聊故事的道德,不要在你的析构函数delete this;
上Object *obj = new Object();
delete obj;
做 [1]
Object obj;
或更好,只是
obj1
[1] or don't do it at all!更准确地指出堆栈溢出实际上是由{{1}}的析构函数触发的。
答案 1 :(得分:3)
'删除这个'永远不会有意义。你要么在这里引起无限递归,要么你正在删除某个对象,而它还在被其他人使用。只需删除它。该对象已被删除:这就是你在析构函数中的原因。
答案 2 :(得分:3)
您遇到的崩溃是由于以下声明:
{
Object obj1;
}
这会在堆栈上分配“对象”的实例。您创建它的范围结束,因此对象超出范围,因此调用析构函数(Object :: ~Object)。
{
Object obj1;
// automatic
obj1.~Object();
}
这意味着应用程序将遇到的下一条指令是
delete this;
这里有两个问题:
delete
调用对象的析构函数,因此析构函数间接调用析构函数,间接调用析构函数... delete
尝试将对象的内存返回到new
从中获取它的位置。相比之下
{
Object *obj2 = new Object();
}
这会创建一个堆栈变量obj2
,它是一个指针。它在堆上分配内存来存储Object的实例,调用它的默认构造函数,并将新实例的地址存储在obj2
中。
然后obj2
超出范围,没有任何反应。 Object
没有被释放,也没有被调用的析构函数:C ++没有自动垃圾收集,并且当指针超出范围时没有做任何特殊事情 - 它肯定不会释放内存。
这是内存泄漏。
经验法则:delete
来电应与new
来电相匹配,delete []
与new []
相匹配。特别是,请尝试将new
和delete
保留在匹配的权限区域中。以下是不匹配的所有权/权限/责任的示例:
auto* x = xFactory();
delete x;
同样地
auto* y = new Object;
y->makeItStop();
相反,你应该更喜欢
// If you require a function call to allocate it, match a function to release it.
auto* x = xFactory();
xTerminate(x); // ok, I just chose the name for humor value, Dr Who fan.
// If you have to allocate it yourself, you should be responsible for releasing it.
auto* y = new Object;
delete y;
C ++有容器类,可以为您管理指针的对象生存期,请参阅std::shared_ptr,std::unique_ptr。
答案 3 :(得分:1)
这里有两个问题:
delete
,这通常是代码气味delete this
,这有几个问题 指南:您不应使用new
和delete
。
<强>原理强>:
delete
而不依赖于智能指针(并且通常是自动清理)脆弱,不仅原始指针的所有权不清楚(你确定你应该删除它吗?)但是还不清楚你是否真的在每个需要它的 上调用delete
,尤其是在存在异常< / em> =&gt;做你的理智(以及你的同伴的理智),不要使用它。使用new
也容易出错。首先,您确定需要在堆上分配内存吗? C ++允许在堆栈上进行分配,C ++标准库具有容器(vector
,map
,...),因此需要动态分配的实际实例很少且很远。此外,如上所述,如果你达到动态分配,你应该使用智能指针;为了避免执行问题的微妙顺序,建议您使用工厂函数:make_shared
和make_unique
(1)来构建所述智能指针。
(1)make_unique
在C ++ 11中不可用,仅在C ++ 14中,它可以通过以下方式实现(使用new
,当然:p)
指南:您不得使用delete this
。
<强>理由:强>
使用delete this
意味着,从字面上看,锯掉了你所坐的分支。
delete
的参数应始终是动态分配的指针;因此,如果您无意中在堆栈上分配了最有可能导致程序崩溃的对象实例。我已经看到了几个使用示例,但没有一个不能使用传统的替代方案。