0

カスタム Array クラスを作成し、次のコンストラクターがあるとします。

    Array::Array(size_t size)
    {
      mySize = size;
      //myData is of type int*
      myData = new int[mySize]; // this stuff is allocated on a heap
    }

私の知る限り、この場合のデフォルトのコピー コンストラクターは次のように実装されます。

    Array::Array(Array& a)
    {
      mySize = a.mySize;
      myData = a.myData; //points to the same memory on the heap
    }

最後に、main.cpp ファイルに次のコードがあるとします。

     int main()
     {
       Array a(1);
       Array b(a); //copy constructor is invoked
     }

私が予想していたのは、フリー ストア メモリへの myData ポインタの削除によるメモリ リークでしたが、次のランタイム エラーが発生しました。

*** glibc detected *** ./main.out: double free or corruption (fasttop): 0x086ad008 ***

なぜ?~Array() は、ヒープに割り当てられたメモリを自動的に解放するようですが、これは私にとって非常に直感的ではありません。多分私は何かを逃していますか?

アップデート:

      class Array{
         private:
           size_t mySize;
           int *myData;
           ...

更新 2:

main.cpp:

   #include <iostream>
   #include "array.h"

   int main()
   {
     Array a(1);
     Array b(a);
   }

配列.h:

   #ifndef ARRAY_H_
   #define ARRAY_H_
   #include <stddef.h>
   class Array{
   private:
       size_t mySize;
       int *myData;
   public:
       Array(size_t size);
       ~Array();
       void set(int i,int val);
       int get(int i);
       size_t getSize();
   };
   #endif

配列.cpp:

   #include "array.h"

   Array::Array(size_t size)
   {
     mySize = size;
     myData = new int[mySize];
   }

   Array::~Array()
   {
     delete[] myData;
   }

   void Array::set(int i, int val)
   {
     if(i>=0 && i<mySize)
       myData[i] = val;
   }

   int Array::get(int i)
   {
     if(i>=0 && i<mySize)
       return myData[i];
     else return -1;
   }
   size_t Array::getSize()
   {
     return mySize;
   }
4

5 に答える 5

4

私はあなたのデストラクタであなたが持っていると思います

 Array::~Array(void)
 {
      delete [] myData; //points to the same memory on the heap
 }

問題はダブルフリー

例:

int main()
{
       Array a(1);  // here a.myData = 0x12345678
       Array b(a); //copy constructor is invoked // here b.myData = 0x12345678

       // pop  stack (call destroy of object)
       // delete b.myData
       // delete a.myData already delete
}

ダブルフリー

編集:const aを変更しないため 、コピーコンストラクターで使用します。

 Array::Array(const Array& a)
 {
      mySize = a.mySize;
      myData = a.myData; //points to the same memory on the heap
 }

幸運を !

于 2013-03-06T21:59:38.933 に答える
3

だから...あなたの主張にもかかわらず、あなたはデストラクタの配列を削除し、コピーコンストラクタは浅いコピーなので、二重削除を取得することがわかりました単純。

Array::~Array()
{
  delete[] myData;
}

これは動的配列であるため、データを所有する必要があります。したがって、デストラクタで削除する権利がありますが、コピーコンストラクタと代入演算子で「ディープ」コピーを行う必要があります。三つのルールを参照してください。

于 2013-03-06T22:11:50.607 に答える
2

コピーは浅いコピーであるため、メモリを解放するデストラクタがある場合、各オブジェクトは同じメモリを削除しようとします。

浅いコピーを行う必要はありません実際のデータを新しく割り当てられた配列にコピーする独自の明示的なコピー コンストラクターを作成できます。

コピーおよび代入コンストラクターを無効にし、明示的な方法を優先するという Google の提案が気に入っていますCopyFrom()

于 2013-03-06T22:02:40.110 に答える
1

「ダブルフリー」とは、同じポインタがdelete[]2 回与えられたことを意味します。あなたのデストラクタでは(おそらく)delete[]objectab. 実用的な解決策:std::vector生の配列などを不必要にいじらないでください。

于 2013-03-06T22:00:01.427 に答える
0

(配列 'a' および 'b' からの) デストラクタが同じメモリを解放しようとしていると思います (二重解放)。解放する前に myData を確認する必要があるかもしれません。

于 2013-03-06T22:03:05.597 に答える