为什么这不是C ++中的内存泄漏? [英] Why is this not a memory leak in C++?

查看:76
本文介绍了为什么这不是C ++中的内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

A couple of months ago I asked this question where I asked why there was a memory leak. Apparently, I forgot a virtual destructor.

现在我正在努力了解为什么这不是内存泄漏:

Now I'm struggling to understand why this is not a memory leak:

#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的虚拟析构函数.

Note that I do not have a virtual destructor for Base.

我认为,因为我有一个类型为unique_ptr<Base>的向量m,所以只有Base的析构函数被调用,而我的Derived中的变量b_会泄漏,但是根据valgrind并不是这样. 为什么这不是内存泄漏?

I thought that because I have a vector m of type unique_ptr<Base> only the destructor from Base gets called and my variable b_ in Derived would leak but according to valgrind this is not the case. Why is this not a memory leak?

我已经用valgrind-3.13.0对此进行了测试

I have tested this with valgrind-3.13.0

推荐答案

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

Deleting an object via a polymorphic pointer when the base class doesn't have a virtual destructor is undefined behaviour.

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

Undefined behaviour may mean your code leaks memory, crashes or works perfectly.

在这种情况下,运行时库可能为您的对象分配了一个内存块,并且即使该块被其他类型的指针指向,也能够正确删除该内存块.对于大多数运行时而言,这可能是正确的,但并不能保证.例如.当使用malloc()free()时,无需将malloc()的大小提供给free(),在这里也是如此.

In this case the runtime library presumably allocated a single block of memory for your object and is able to delete that block correctly even when it is pointed to by a pointer of a different type. This is probably true for most runtimes but there are no guarantees. E.g. when using malloc() and free() you don't need to supply the size of the malloc() to free(), the same is happening here.

如果您在Derived中定义了一个析构函数,则会看到没有被调用.

If you had defined a destructor in Derived you would see that it is not being called.

这篇关于为什么这不是C ++中的内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆