2017-04-23 3 views
-3

m_Arrayの削除には多くの問題があります。プログラムは、クリーンアップ部分を実行しているときに最後にセグメンテーションを行います。私は、m_Arrayに異なるデータを持つ2つのクラスAオブジェクトを持っています。そして、あるオブジェクトからのデータは、別の配列に "折り返し"始めて不正なデータを引き起こします。 Tは私のテンプレートデータ型を表します。C++ペアの動的なサイズの配列の削除に問題があります

ちょうど2つのクラスAのようなクラス宣言に公に宣言

オブジェクトを作成し、クラスBは、もあります:

template <typename T> 
A<T>::A(int size) { 

    // Set array size 
    m_Array = new pair<T, int>[size]; 

    // Initialize values 
    for (int i = 0; i < size; i++) { 
     m_Array[i] = make_pair(-1, -1); 
    } 

    //... other things defined and initialized...// 
} 
:ようなクラスAのコンストラクタ定義で定義された

template <typename T> class A 
{ 
public: 
    pair<T, int> *m_Array; // Array of type pair 
    A(int size=1);  // constructor 
    ~A();  // A destructor 

    // ... all other definitions // 

}; 

クラスAのデストラクタ:

template <typename T> 
A<T>::~A() { 

     delete [] m_Array; // Not working as it should 
} 

オーバーロード代入演算子

template <typename T> 
const A<T>& A<T>::operator=(const A<T>& rhs) { 
    m_AArraySize = rhs.m_AArraySize; 
    m_currASize = rhs.m_currASize; 

    for (int i = 0; i < m_currASize; i++) { 

     m_Array[i].first = rhs.m_Array[i].first; 
     m_Array[i].second = rhs.m_Array[i].second; 
    } 

    _ptr = rhs._ptr; 

    return *this; 
} 

コピーコンストラクタ

template <typename T> 
A<T>::A(const A<T>& other) { 
    m_AArraySize = other.m_AArraySize; 
    m_AHeapSize = other.m_AHeapSize; 

    for (int i = 0; i < m_currASize; i++) { 
     m_Array[i].first = other.m_Array[i].first; 
     m_Array[i].second = other.m_Array[i].second; 
    } 

    _ptr = other._ptr; 
} 

クラスB宣言

template <typename T> class B{ 
public: 
    //B constructor 
    B(int size); 


    int m_currBSize;  // spots used in array 
    int m_BSize;   // size of array 

    A <T> oneAHolder; 
    A <T> twoAHolder; 

}; 

クラスBコンストラクタ

template <typename T> 
b<T>::b(int size){ 
    A<T>(size); 

    m_BArraySize = size; 
    m_currBSize = 1; 

    // Create two A objects 
    A<T> oneA(size); 
    A<T> twoA(size); 

    // oneA and twoA go out of scope 
    oneAHolder = oneA; 
    twoAHolder = twoA; 
} 

私の主な機能では、クラスBオブジェクトを作成し、そのAオブジェクトの両方にデータを挿入する挿入機能を使用しています。

私は配列からデータを削除し、データを他の配列にあふれさせるのをやめさせましたが、役に立たなかったのです。

ご協力いただきありがとうございます。

PSは:なし

EDIT "だけのstd ::ベクトルを使用" してください:

1):あなたが投稿コードを考えると、私のコード

+2

「ラップアラウンド」とはどういう意味ですか?それは私にとって二重の自由な問題のように聞こえる。あるオブジェクトを別の 'A newA = anotherA'に代入していますか?このhttps://stackoverflow.com/questions/7823845/disable-compiler-generated-copy-assignment-operatorを見たり、それらの機能を実装したりしてください。 –

+1

あなたの 'main'プログラムを私たちに教えてください。あなたが投稿したもので、プログラムは2行のコードで簡単に壊れることがあります。 – PaulMcKenzie

+1

"単にstd :: unique_ptrを使用してください" –

答えて

1

、より多くのを追加しましたあなたの代入演算子は二つの問題があります古いメモリの割り当てを解除できなかったため、割り当て演算子はメモリをリークします。 this->m_Arrayない限り

2)this->m_Arrayrhs.m_Arrayよりも小さいバッファであるので、あなたはforループでメモリを上書きされ、すでに十分な大きさでした。

この不良コードの代わりに、copy/swap idiomを使用してもかまいません。

#include <algorithm> 
//... 
template <typename T> 
A<T>& A<T>::operator=(const A<T>& rhs) 
{ 
    A<T> temp(rhs); 
    std::swap(temp.m_AArraySize, m_AArraySize); 
    std::swap(temp.m_currASize, m_currASize); 
    std::swap(temp.m_Array, m_Array); 
    std::swap(temp._ptr, _ptr); 
    return *this; 
} 

あなたは間接的に代入演算子を呼び出し、デストラクタが修正されない正しいコピーコンストラクタを書かれている場合、これは動作します。これらの機能のいずれかに障害がある場合、上記の方法は機能しません。

コピーコンストラクタとデストラクタにバグがないと仮定すると、このように代入演算子を記述すると、コピーコンストラクタのコードを再作成する必要がなくなります。

Aにあなたの投稿に指定していないメンバー変数がさらにある場合は、それらもすべてスワップする必要があります。

つまり、これは基本的にはrhsのコピーを作成し、古いデータをすべてthisからtempに交換します。その後、tempは古いデータで終了します。

関連する問題