Jac*_*ack 1 c++ destructor memory-management visual-c++
所以我是一个初学者,试图掌握操作员新手.我的析构函数有什么问题?
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;
}
Run Code Online (Sandbox Code Playgroud)
离开.~arr(); 在给我这个错误:
调试断言失败了!文件:dbgdel.cpp行:52
表达式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)
我不明白为什么pool2工作正常,但使用该类给我带来了问题.系统"暂停"后也会弹出错误,这是在.~arr()被调用之后???
谢谢!
嗯,一目了然,你不应该明确地调用析构函数.而是使用作用域强制超出范围并调用析构函数.
int main()
{
{
arr a;
} //This calls destructor of a
//Rest of code
}
Run Code Online (Sandbox Code Playgroud)
否则,a的析构函数会被调用两次:一次调用它时,一次调用超出范围时.
编辑:
你去吧.
http://www.parashift.com/c++-faq-lite/dtors.html
问题是您在a(a.~arr())上显式调用析构函数,而在结束时超出范围时,析构函数将自动被调用.当第二次调用析构函数时,会在已经被破坏的对象上调用它.从技术上讲,这会导致未定义的行为(根据C++标准,这可以说任何结果都可以.)在实践中,这段代码可能只是再次执行析构函数,将存储在以前存储器位置的地址传递给(运行时可能存在或者可能不存在构造函数),这是由Debug运行时捕获的.amain()a.pool::operator delete()
如果你想a在中间删除,你应该做的main()是引入一个额外的范围:
int main()
{
{
arr a;
} //a will be deleted here
// rest of main
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是不使用自动对象,而是使用动态对象,您可以为其设置生命周期.
但是你的代码存在另一个问题,你没有问过,但我觉得有必要指出:
您的班级迫切需要一个复制构造函数和赋值运算符.(至少,声明它们private是为了禁止复制.)根据规则三,你需要一个析构函数的事实应该给你一个暗示,其他两个也是需要的.
您可以通过不尝试手动管理动态分配的内存来避免所有麻烦.而是使用为您执行此操作的类型:
class arr{
public:
arr() : pool(100*sizeof(double)) {
}
// ~arr() // not needed any longer
std::vector<char> pool;
};
Run Code Online (Sandbox Code Playgroud)