0

テンプレートを使用して一般的なリストを作成しようとしています。このリストは、要素の数を取得するための整数である Pointer 配列 T* といくつかのメソッド (find、contains...) によって合成されます。

私の問題は、たとえば、作業しているときに発生List<List<int> >します。

メソッドの1つはT*ポインター配列のサイズを変更するため、これがある場合List<List>>、より大きなサイズのauxpointerを作成し、コンテンツをauxpointerにT*コピーします. 内側の Pointers( ) もポインタとしてコピーされ、メモリは複製されないため、ポインタを削除して再署名すると. 私はすでにそのポインタのデータを失っています.Tmemcpylist.T.TT*T=auxpointernew T

template <typename T>
void CGenericList<T>::resize()
{
    T* auxPointer = new T[this->maxElements*2];
    memcpy (auxPointer,this->pointer,this->maxElements*sizeof(T));
    delete[] this->pointer;     
    this->pointer=auxPointer;
    this->maxElements=2*this->maxElements;
}

template<class T>
class CGenericList
{
public:
    T* pointer;
    int N;
    int maxElements;

    CGenericList();
    CGenericList(int);
    ~CGenericList();
    void resize();  
}

誰でもそれを行うためのヒントを教えてもらえますか?

4

2 に答える 2

3

投稿したコードにはいくつかの問題があります。

T* auxPointer = new T[this->maxElements*2];

ここで maxElements*2 の新しい配列を割り当て、デフォルトのコンストラクターを呼び出します。あなたの場合、おそらくすべてのリスト要素を初期化します。

memcpy (auxPointer,this->pointer,this->maxElements*sizeof(T));

その後、古い配列の内容を新しく割り当てられたメモリのメモリ領域にコピーします。これにより、作成されたばかりの Listelements へのポインターが古い配列のポインターで上書きされます -> メモリ リーク。

delete[] this->pointer;

次に、配列を削除すると、すべての要素のデストラクタが呼び出されます。うまくいけば、コンテンツが削除され、メモリが解放されます。

this->pointer=auxPointer;

最後に、新しく作成した配列を再割り当てします。リスト内のポインターは古いリスト要素を指し、もう割り当てられていないメモリを指します (delete[] によるデストラクタへの呼び出しのため)。

解決策は、リストのコピー コンストラクターを実装し、配列内のすべての要素に対してそれを呼び出すことです。(DeepCopy) そしてもちろん代入演算子、私はほとんど忘れていました;)

CGenericList(const CGenericList<T>& copy);
CGenericList<T>& operator= (const CGenericList<T>& rhs)

おそらくこのようなものです-これは「asis」であり、例外的に安全ではないことに注意してください;)

template<class T>
class CGenericList
{
public:
    T* pointer;
    int N;
    int maxElements;

    CGenericList();
    CGenericList( const CGenericList<T>& copy );
    CGenericList<T>& operator=(const CGenericList<T>& rhs);
    CGenericList(int);
    ~CGenericList();
    void resize();
};

template <typename T>
void CGenericList<T>::resize()
{
    T* auxPointer = new T[this->maxElements*2];
    for(int i=0; i < this->maxElements; i++)
    {
        auxPointer[i] = this->pointer[i];
    }
    delete[] this->pointer;
    this->pointer = auxPointer;
    this->maxElements = this->maxElements*2;
}

template <typename T>
CGenericList<T>::CGenericList()
    :N(0)
    ,maxElements(0)
{
    this->pointer = new T[1];
}

template <typename T>
CGenericList<T>::CGenericList(const CGenericList<T>& copy)
    :N(copy.N)
    ,maxElements(copy.maxElements)
{
    T* temp = new T[copy.maxElements];
    for(int i=0; i<N; i++ )
    {
        temp[i] = copy.pointer[i];
    }
    this->pointer = temp;
}

template <typename T>
CGenericList<T>& CGenericList<T>::operator=(const CGenericList<T>& rhs)
{
    if( this != &rhs )
    {
        delete[] this->pointer;
        this->pointer = new T[rhs.maxElements];
        for(int i=0; i<rhs.maxElements; i++)
        {
            this->pointer[i] = rhs.pointer[i];
        }
    }
    return *this;
}


template <typename T>
CGenericList<T>::CGenericList(int size)
    :N(0)
    ,maxElements(size)
{
    this->pointer = new T[size];
}

template <typename T>
CGenericList<T>::~CGenericList()
{
    delete[] this->pointer;
}


int main(int /*argc*/, char */*argv*/[])
{
    CGenericList<CGenericList<int> > list;
    list.resize();

    return 0;
}

stl を使いたくない場合は、stlportを参照してください。

于 2012-05-24T10:27:59.130 に答える
0

あなたresizeは例外安全ではありません。最初に既存の配列を削除してから、別のサイズにメモリを割り当ててから、auxPointer を割り当てます。
あなたが抱えている問題に来て、以下のアプローチが役立つかどうかを確認してください.

T* auxPointer = new T[this->maxElements*2];       
for ( int i =0; i < this->maxElements; ++i)
   std::swap(auxPointer[i], pointer[i]);

delete[] this->pointer;    
this->pointer = auxPointer;  
this->maxElements=2*this->maxElements;
于 2012-05-24T09:24:15.107 に答える