几个月前我问过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/