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

use*_*005 3 c++ valgrind memory-leaks undefined-behavior unique-ptr

几个月前,我问过这个问题,我问为什么会有内存泄漏.显然,我忘记了一个虚拟的析构函数.

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

我想是因为我有一个vector m类型的unique_ptr<Base>只能从析构函数Base被调用,我的变量b_Derived会泄露,但根据Valgrind的情况并非如此.为什么这不是内存泄漏?

我用valgrind-3.13.0测试了这个

Ala*_*les 5

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

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

在这种情况下,运行时库可能为您的对象分配了一个内存块,并且即使它被不同类型的指针指向,也能够正确地删除该块.大多数运行时可能都是这样,但是没有保证.当使用EG malloc()free()你没有需要提供的大小malloc()free(),同样发生在这里.

如果你已经定义了析构函数,Derived你会发现它没有被调用.