【问题标题】:C++ inheritance and valgrind memory leakC++ 继承和 valgrind 内存泄漏
【发布时间】:2020-06-23 21:39:29
【问题描述】:

我正在使用 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;
}

代码中没有什么花哨的。有基类,我想在最后一个类中获取一个指针作为第一个基类的指针。

当我编译这个 valgrind 时显示 4 allocs 3 frees。

这段代码有什么问题?也许我误解了继承的概念。然而,当我将 something 函数称为

something("blabla")

没有打印错误。

【问题讨论】:

  • 你需要声明一个虚拟析构函数。
  • (zoo *) in (zoo *) new foo(1,2,str); 不是必需的,应该删除。它可能会在将来隐藏错误。此外,(foo*) 应该是 dynamic_cast&lt;foo*&gt;(ex)。应该避免使用像 (foo*)(zoo*) 这样的 C 风格转换并将其视为危险。如果您真的需要强制转换,请改用更弱且更显式的 C++ 强制转换。
  • 是的虚拟析构函数解决了@VladfromMoscow 的问题。我猜当我给一个小字符串时,Valgrind 会以某种方式看到它被释放了。
  • @fbgencer 那可能是因为编译器使用了short string optimization,这里使用了一个小数组,而不是为字符串动态分配内存。

标签: c++ inheritance valgrind destructor virtual-destructor


【解决方案1】:

由于基类没有虚析构函数,所以在这个语句中

delete ex;

根据指针的静态类型,只调用类zoo的析构函数。此语句中创建的foo 类型对象的子对象

return (zoo *) new foo(1,2,str);

不会被破坏。

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

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

【讨论】:

    猜你喜欢
    • 2011-10-04
    • 2020-03-31
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多