运算符新建/删除&析构函数
所以我是一个初学者,试图掌握operator new。我的析构函数出了什么问题?
class arr{
public:
arr(){
pool=::operator new(100*sizeof(double));
}
~arr(){
::operator delete(pool);
}
void* pool;
};
int main()
{
arr a;
a.~arr(); //If I comment this out it's ok.
void* pool2=::operator new(100*sizeof(double)); //Works
::operator delete(pool2); //Fine.
system("pause");
return 0;
}
留下a.~arr();给我这个错误:
调试断言失败!文件:dbgdel.cpp line:52
表达式:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
我不明白为什么 pool2 工作正常但使用该类给我带来了问题。此外,该错误仅在系统“暂停”后才会弹出,即在调用 a.~arr() 之后???
谢谢!
So I'm a beginner trying to get to grips with operator new. What's wrong with my destructor?
class arr{
public:
arr(){
pool=::operator new(100*sizeof(double));
}
~arr(){
::operator delete(pool);
}
void* pool;
};
int main()
{
arr a;
a.~arr(); //If I comment this out it's ok.
void* pool2=::operator new(100*sizeof(double)); //Works
::operator delete(pool2); //Fine.
system("pause");
return 0;
}
Leaving a.~arr(); in gives me this error:
Debug assertion failed! File: dbgdel.cpp line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
I can't see why pool2 works fine but using the class gives me problems. Also the error only pops up after the system "pauses", which is after a.~arr() is called???
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
嗯,乍一看,您不应该显式调用析构函数。相反,使用作用域来强制超出范围并调用析构函数。
否则,a 的析构函数会被调用两次:一次是在调用它时,另一次是在 a 超出范围时。
编辑:
给你。
http://www.parashift.com/c++-faq-lite/dtors.html
Well, at a glance, you should not be explicitly calling the destructor. Instead use scoping to force a out of scope and call the destructor.
Otherwise the destructor of a gets called twice: once when you call it and again when a goes out of scope.
EDIT:
Here ya go.
http://www.parashift.com/c++-faq-lite/dtors.html
问题是您在
a
(a.~arr()
) 上显式调用析构函数,而析构函数已经被自动调用 当a
在main()
末尾超出范围时。当第二次调用析构函数时,在已析构的对象上调用。从技术上讲,这会导致未定义行为(这是一种表示根据 C++ 标准任何结果都很好的方式)。实际上,这段代码可能只是再次执行析构函数,将存储在曾经是a.pool
的内存位置中的地址传递给::operator delete()
(这可能是也可能不是构造函数存储在那里的内容),由调试运行时捕获。如果您希望在
main()
中间删除a
,您应该做的是引入一个额外的作用域:另一种方法是不使用自动对象,但是一个动态对象,您可以为其设置生命周期。
但是您的代码还有另一个问题,您没有询问,但我仍然觉得有必要指出:
您的班级迫切需要一个< em>复制构造函数和赋值运算符。 (至少,将它们声明为
私有
以禁止复制。)根据三法则,您需要一个析构函数的事实应该给您一个暗示,即还需要其他两个。您可以通过不尝试手动管理动态分配的内存来避免所有麻烦。相反,使用可以为您执行此操作的类型:
The problem is that you explicitly invoke the destructor on
a
(a.~arr()
), while the destructor will already be invoked automatically whena
goes out of scope at the end ofmain()
. When the destructor is called for the second time, it is called on an already destructed object. Technically, this leads to Undefined Behavior (which is a way to say that any result will be fine according to the C++ standard). In practice this code will likely just execute the destructor again, passing the address stored in the memory location that used to bea.pool
to the::operator delete()
(which might or might not be what the constructor stored there), which is caught by the Debug runtime.What you should do instead if you want
a
to be deleted in the middle ofmain()
is to introduce an additional scope:Another way would be to not to use an automatic object, but a dynamic one, for which you can set a lifetime.
But there's another problem with your code, which you didn't ask about, but which I nevertheless feel a need to point out:
Your class urgently needs a copy constructor and a assignment operator. (At the very least, declare them
private
in order to disallow copying.) As per the Rule Of Three, the fact that you need a destructor should give you a hint that the other two are needed as well.You can avoid all the hassle by not attempting to manually manage dynamically allocated memory. Instead use a type which does this for you:
您不需要为堆栈上创建的对象调用析构函数。变量“a”位于堆栈中,超出范围时将自动删除。
you don't need to call destructor for objects created on stack. The variable 'a' is on stack and will be deleted automatically when out of scope.