c++ - 为什么这不是 C++ 中的内存泄漏?

标签 c++ memory-leaks valgrind undefined-behavior unique-ptr

几个月前我问过this question 我在哪里问为什么会出现内存泄漏。显然,我忘记了一个虚拟析构函数。

现在我很难理解为什么这不是内存泄漏:

#include <iostream>
#include <vector>
#include <memory>


using namespace std;

class Base{
public:
    explicit Base(double a){
        a_ = a;
    }
    virtual void fun(){
        cout << "Base " << a_ << endl;
    }

protected:
    double a_;
};


class Derived : public Base{
public:
    Derived(double a, double b): Base(a), b_{b}{
    }
    void fun() override{
        cout << "Derived " << a_ << endl;
    }
private:
    double b_;
};



int main() {

    vector<unique_ptr<Base> > m;

    for(int i=0; i<10; ++i){
        if(i%2 == 0){
            m.emplace_back(make_unique<Base>(i));
        }else{
            m.emplace_back(make_unique<Derived>(i, 2*i));
        }
    }

    for(const auto &any:m){
        any->fun();
    }

    return 0;
}

请注意,我没有 Base 的虚拟析构函数.

我以为是因为我有一个 vector m类型 unique_ptr<Base>只有来自 Base 的析构函数被调用,我的变量 b_Derived会泄漏,但根据 valgrind 的说法,情况并非如此。 为什么这不是内存泄漏?

我已经用 valgrind-3.13.0 测试过了

最佳答案

当基类没有虚析构函数时通过多态指针删除对象是未定义的行为。

未定义的行为可能意味着您的代码泄漏内存、崩溃或完美运行。

在这种情况下,运行时库可能会为您的对象分配单个内存块,并且即使当它被不同类型的指针指向时也能够正确删除该 block 。对于大多数运行时来说,这可能是正确的,但不能保证。例如。使用 malloc()free() 时,您不需要将 malloc() 的大小提供给 free( ),同样的事情也发生在这里。

如果您在 Derived 中定义了一个析构函数,您会发现它没有被调用。

关于c++ - 为什么这不是 C++ 中的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53413647/

相关文章:

c - Valgrind 显示的以下内存泄漏有多严重

c++ - RSA_sign 和 RSA_verify 不同的行为

c++ - 有时我在反转数组时会遇到 EXEC_BAD_ACCESS (访问冲突)

c++ - 指向固定大小数组的指针的析构函数

memory-leaks - 元空间内存泄漏

linux - 是否有与 freebsd hwpmc 等效的 linux/端口?

c++ - 如何在 Eigen 中对矩阵进行逐行裁剪?

Linux 内核内存泄漏目前已修复

ios - CoreImage/CoreVideo 中的内存泄漏

c - 在 C 程序中使用 Valgrind