我不知道如何在下面的代码示例中正确释放obj2,我尝试使用虚拟析构函数,但由于char指针m_s没有被分配,引发了异常。
#include <iostream>
using namespace std;
class A
{
private:
char *m_s;
public:
A() { m_s = strdup("default"); }
A(char *s) { del_data(); m_s = strdup(s); }
A(const A& a) { del_data(); m_s = strdup(a.m_s); }
virtual void prepare() { cout << "A "; }
void display() {
prepare();
cout << m_s << endl;
}
void del_data()
{
if (m_s)
{
free(m_s);
}
m_s = nullptr;
}
virtual ~A()
{
del_data();
}
};
class B : public A
{
public:
B(char *s) : A(s) { }
B(const B &b) : A(b){}
void prepare() { cout << "B "; }
~B() {
A::del_data();
}
};
void foo(A *obj1, A obj2) {
obj1->display();
obj2.display();
}
int main() {
B obj1("text");
A *obj2 = new B(obj1);
foo(&obj1, *obj2);
delete obj2;
return 0;
}
当我删除obj2时,应该调用类B的析构函数,并且del_data()方法应该释放分配的内存并将m_s设置为nullptr。不知何故,它并不像预期的那样工作,我甚至尝试使用delete[]也无济于事。
我很想知道我做错了什么,以及如何在未来避免这种错误。
谢谢你的时间。
2条答案
按热度按时间xxslljrj1#
你的代码中有很多问题,但是segfault来自于
m_s
没有被初始化,因此你在一个随机地址上调用了del_data
。与稳定性和正确覆盖虚函数有关的其他问题。你不需要像以前那样实现~B()
:~A()
将被自动调用。然而,在设计方面,您正在使用类似C的字符串API。我强烈建议使用std::string,这样在这种情况下会保存很多麻烦。
下面用C字符串修复。我把转换到std::string作为练习留给你;)
Live
nkhmeac62#
如果在构造函数中调用的del_data()是用未初始化的m_s调用的(其值未指定)初始化为nullptr将修复它。
但是没有理由在构造函数中调用它-它永远不会指向必须释放的内存。