C++ C++;继承和内存泄漏

C++ C++;继承和内存泄漏,c++,inheritance,valgrind,destructor,virtual-destructor,C++,Inheritance,Valgrind,Destructor,Virtual Destructor,我正在用valgrind检查我的代码,它发现了内存泄漏。我不明白为什么会这样。我没有编写主代码,而是编写了一个类似的程序来检查是我的其他分配(字符数组等)导致了问题还是类导致了问题 class zoo{ public: int x; zoo(int a){x = a;}; }; class doo:public zoo{ public: int y; doo(int a,int b):zoo(a){y = b;}; }; class foo : public

我正在用valgrind检查我的代码,它发现了内存泄漏。我不明白为什么会这样。我没有编写主代码,而是编写了一个类似的程序来检查是我的其他分配(字符数组等)导致了问题还是类导致了问题

class zoo{
public:
    int x;
    zoo(int a){x = a;};
};

class doo:public zoo{
public:
    int y;
    doo(int a,int b):zoo(a){y = b;};
};

class foo : public doo{
public:
    String z;
    foo(int a, int b, const char *c):doo(a,b){
        z = c;
    };
};

zoo * something(const char * str){
    return (zoo *) new foo(1,2,str);
}
int main() {
    zoo * ex = something("blabla:sometext:blabla:overflow:message");
    cout<<"msg:"<< ((foo*)ex)->z<<endl;
    delete ex;
    return 0;
}

没有打印错误。

因为基类没有虚拟析构函数,所以在该语句中

delete ex;
return (zoo *) new foo(1,2,str);
根据指针的静态类型,只调用类
zoo
的析构函数。在此语句中创建的
foo
类型的对象的子对象

delete ex;
return (zoo *) new foo(1,2,str);
没有被破坏

至少可以在类
zoo
中定义析构函数

class zoo{
public:
    int x;
    zoo(int a){x = a;};
    virtual ~zoo() = default;
};

你需要声明一个虚拟析构函数。
(zoo*)
(zoo*)新的foo(1,2,str)不是必需的,应该删除。它可能会在将来隐藏错误。另外,
(foo*)
应该是一个
动态演员(ex)
。像
(foo*)
(zoo*)
这样的C风格的类型转换应该避免,并被认为是危险的。如果你真的需要一个演员,使用更弱和更明确的C++演员代替。是的虚拟析构函数解决了问题@ VladfrromMoscow。我猜,当我给一个小字符串时,Valgrind不知怎么地看到它被释放了。@fbgencer这可能是因为编译器使用了一个小数组,而不是为字符串动态分配内存。