在下面的练习中,我创建了一个基类和几个派生类之间的多态关系:
#include <iostream>
using namespace std;
class Panthera
{
public:
virtual void roar() = 0;
virtual ~Panthera() {}
};
class Lion : public Panthera
{
public:
void roar() { cout << "roaring like a lion... " << endl; }
};
class Tiger : public Panthera
{
public:
void roar() { cout << "roaring like a tiger..." << endl; }
};
class Jaguar : public Panthera
{
public:
void roar() { cout << "roaring like a jaguar... " << endl; }
};
class Leopard : public Panthera
{
public:
void roar() { cout << "roaring like a leopard... " << endl; }
};
void speak(Panthera *object)
{
object->roar();
delete object; // this is meant to prevent memory leak
cout << "deleting pointer... " << endl;
}
int main()
{
Lion lion;
Tiger tiger;
Jaguar jaguar;
Leopard leopard;
speak(&lion);
speak(&tiger);
speak(&jaguar);
speak(&leopard);
cout << "program ending... " << endl;
}
我已经将基类析构函数设置为virtual并删除函数“speak”中的指针以防止内存泄漏,而代码编译运行时没有任何警告或错误,我从内存泄漏中得到以下结果检测器:
Error #1: INVALID HEAP ARGUMENT to free 0x0028ff2c
# 0 replace_free [d:\drmemory_package\com...
# 1 Lion::~Lion [../src/bigCats.cpp:11]
# 2 speak [../src/bigCats.cpp:39]
# 3 main [../src/bigCats.cpp:52]
Note: @0:00:01.466 in thread 7936
Error #2: INVALID HEAP ARGUMENT to free 0x0028ff28
# 0 replace_free [d:\drmemory_package\com...
# 1 Tiger::~Tiger [../src/bigCats.cpp:17]
# 2 speak [../src/bigCats.cpp:39]
# 3 main [../src/bigCats.cpp:53]
Note: @0:00:01.482 in thread 7936
Error #3: INVALID HEAP ARGUMENT to free 0x0028ff24
# 0 replace_free [d:\drmemory_package\com...
# 1 Jaguar::~Jaguar [../src/bigCats.cpp:23]
# 2 speak [../src/bigCats.cpp:39]
# 3 main [../src/bigCats.cpp:54]
Note: @0:00:01.497 in thread 7936
Error #4: INVALID HEAP ARGUMENT to free 0x0028ff20
# 0 replace_free [d:\drmemory_package\com...
# 1 Leopard::~Leopard [../src/bigCats.cpp:29]
# 2 speak [../src/bigCats.cpp:39]
# 3 main [../src/bigCats.cpp:55]
Note: @0:00:01.529 in thread 7936
我还注意到该程序偶尔会以随机间隔发生崩溃,尽管它似乎在大多数情况下都有效。奇怪的是,当我摆脱“说话”功能中的“删除对象”命令时,内存泄漏检测器的这些错误完全消失。
有人可以向我解释这里发生了什么吗?我的教科书理解告诉我,我需要删除指向基类的指针以防止内存错误并避免不可预测的程序行为,但我似乎正在经历完全相反的情况。
答案 0 :(得分:2)
在C ++中,您必须仔细管理所有对象的生命周期。
delete x
仅对指向new
创建的对象的指针有效。
您在自动存储中创建了对象。没有必要delete
来防止内存泄漏,并且这样做是未定义的行为。
避免使用&#34;拥有&#34;的原始指针。资源;在必须堆分配时使用unique_ptr
。避免堆分配;学习5的规则,只在需要时分配堆。
答案 1 :(得分:0)
也可以通过使用a隐式调用析构函数 由a构造的对象已分配的delete-expression 新表达;
因此,在使用delete
运算符分配对象时,只能使用new
运算符。
对象的生命周期 - new
未分配的对象一旦超出范围(在您的情况下,当它超出主要的块范围时)将被自动销毁。