以多态方式使用派生类的std::vector成员的复制赋值会导致内存泄漏

copy assignment of std::vector member of a derived class causes memory leak when used in a polymorphic way

本文关键字:赋值 复制 泄漏 内存 成员 vector 派生 多态 std 方式使      更新时间:2023-10-16

在下面的代码中,我想在derived类中存储input vector<double>。我通过应用std::vector的复制赋值来实现这一点,因为将向量传递给setIT函数。我需要使用compute,它是在派生中实现的。在此副本分配过程中出现内存泄漏。

这个泄漏可以通过使用:vector<double> * input而不是vector<double> input来避免,但我不明白为什么。

有人能解释一下吗?提前谢谢。

#include "utilities.h"
#include <fstream>
using namespace std;
using namespace astro;
class base
{
  public:
    base () { cout<<" in base default constructor "<<endl; }
    virtual void setIT (void *v) = 0;
    virtual double compute () = 0;
};
class derived : public base
{
  protected:
    vector<double> input;
  public:
    derived ();
    virtual void setIT (void *v);
    virtual double compute () { /* using input vector to return something */ return 0; }
};
derived::derived () : base()
{
    cout<<" in derived default constructor "<<endl;
    input.resize(0);
}
void derived::setIT (void *v)
{
  cout<<" in derived setIT "<<endl;
  vector<double> * a = reinterpret_cast<vector<double>* >(v);
  input = *a;
  for (uint i = 0; i<input.size(); i++)
    cout<<i<<" "<<input[i]<<endl;
}
int main ()
{
  vector<double> test;
  fill_linear(test,5,1.,6.); // linear filling of test vector by '5' values between 1 and 6
  base * t = new derived;
  t->setIT (&test);
  cout<<t->compute()<<endl;
  delete t;
  t = NULL;
  return 0;
}
输出:

 in base default constructor 
 in derived default constructor 
 in derived setIT 
0 1
1 2.25
2 3.5
3 4.75
4 6
1

实际上你的程序调用了未定义行为。

base的析构函数必须virtual才能定义良好。

只需定义析构函数为:

virtual ~base() {}  

即使为空也要执行此操作!

详情请参阅:

    什么时候我的析构函数应该是虚的?

避免在c++中使用void指针。如果你想处理不同的类型,可以使用模板。

class Base
{
public:
  virtual ~Base(){}
  virtual double compute() const=0;
};
template<typename T>
class Derived : public Base
{
private:
  std::vector<T> m_input;
public:
  void set_it(const T& in)
  {
    m_input = in;
  }
  double compute() const{/*Do the computation and return*/;}
};