1

VS2010のDebug_VLDは、クラスメンバーの作成/初期化/削除に起因するいくつかのメモリリークを明らかにします。

my_memberタイプdouble*のデータメンバーです。コンストラクターでは、

my_member = NULL ;

次に、いくつかの方法で、メモリをに割り当てる必要がありますmy_member。配列のサイズがまだわからないため、コンストラクターでこれを行うことはできません。また、メソッドの呼び出しごとにサイズが異なる場合があります。このメソッドで私が行うことは、メンバーがNULLであるかどうかをチェックすることです。もしそうなら、私はそれにスペースを割り当てます、そうでなければ、私は配列を操作することができます(accesor []でその要素の値を変更します)。のように見えます

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 ;
}

ラインでメモリリークが発生します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_memberするコード内の他の場所がある場合は、はい。3 つのルール (適切に実装されたコピー コンストラクターと代入演算子) に従わない場合、あらゆる種類の問題に遭遇します。NULLdelete[]

これを防ぐには、std::vector<double>代わりに a を使用してください。

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 に答える