1

VS2010 中的 Debug_VLD 揭示了一些来自类成员创建/初始化/删除的内存泄漏。

my_member是 double* 类型的数据成员。在构造函数中,我有

my_member = NULL ;

然后在某种方法中,我需要为my_member. 我不能在构造函数中这样做,因为我还不知道数组的大小,和/或方法的不同调用的大小可能不同。我在这种方法中所做的是检查成员是否为 NULL。如果是,我为它分配空间,如果不是,我可以对数组进行操作(使用访问器 [] 更改其元素的值)。看起来像

void MyClass::my_method()
{
    if( my_member == NULL )
        my_member = new double[n_dim] ;

    for(int k = 0 ; k < n_dim ; k++ )
         my_member[k] = k ;
}

并且内存泄漏发生在 line my_member = new double[n_dim] ;

在析构函数中,我有

delete[] my_member ;

怎么了?如何正确分配?

谢谢!

4

2 回答 2

3

使用std::vector<double>是首选方式,但如果你想拥有原始double*和编写复制构造函数、移动构造函数和operator=“手动”,你应该这样做:

#include <assert.h>  // for assert

#include <algorithm> // for std::swap

class MyClass
{
  //
  // Raw array
  //
  double * m_ptr; // raw pointer
  size_t m_dim;   // number of items in the array

public:

  // Default constructor - creates empty vector
  MyClass()
    : m_ptr(nullptr)
    , m_dim(0)
  {
  }


  // Copy constructor
  MyClass(const MyClass& src)
    : m_ptr(nullptr)
    , m_dim(0)
  {
    // Special case of empty source
    if (src.m_dim == 0)
    {
      assert(src.m_ptr == nullptr);
      return;
    }

    // Allocate and deep-copy from source
    m_ptr = new double[src.m_dim];
    m_dim = src.m_dim;
    for (size_t i = 0; i < m_dim; i++)
      m_ptr[i] = src.m_ptr[i];
  }

  // Move constructor: steal the "guts" from src
  MyClass(MyClass&& src)
  {
    m_ptr = src.m_ptr;
    src.m_ptr = nullptr;

    m_dim = src.m_dim;
    src.m_dim = 0;
  }

  // Destructor
  ~MyClass()
  {
    delete [] m_ptr;
  }

  // Unified operator=
  MyClass& operator=(MyClass src)
  {
    std::swap(m_ptr, src.m_ptr);
    std::swap(m_dim, src.m_dim);
    return *this;
  }
};
于 2012-10-22T19:21:37.357 回答
2

如果代码中有任何其他地方您my_memberNULL没有调用的情况下设置delete[],那么是的。如果你不遵守三法则(正确实现的复制构造函数和赋值运算符),你会遇到各种各样的麻烦。

为防止这种情况,请改用 a std::vector<double>,您可以在其中执行以下操作:

void MyClass::my_method()
{
    my_member.resize(n_dim); // yay, learned something new here 
    for(int k = 0 ; k < n_dim ; k++ )
         my_member[k] = k ;
}

这样,您就不会管理内存,因此不需要析构函数(除非它是virtual,在这种情况下它可以为空)。

于 2012-10-22T19:01:44.760 回答