-2

これが私のコードです:

template<class T> class Test 
{
    public:
    int Size = 0;
    int Length = 0;
T* Items; 

    Test() {}

~Test() 
    {  
    delete [] Items; 
    }

    void Append(const T& newItem) 
{
        if (Size + 1 >= Length)
    {   
        Length += 250;
            T* old = Items; 
        Items = new T[Length + 250]; 
            for (int i = 0; i < Size; i++) 
           Items[i] = old[i];
            delete [] old; 
        }

        Items[Size] = newItem;  
    Size++;
} 
};

Test<int> test;
for (int i = 0; i < 500000; i++)
   test.Append(i);

動的配列に 500000 個の整数を入力していますが、これには 1 ~ 2Mb しか必要ありませんが、約 30Mb かかります。初期サイズを 500000 に設定しても問題ありません (つまり、サイズ変更は発生しません)。成長値 (250) は何らかの形でメモリに影響を与えるようです。それが大きい場合 (たとえば 1000)、メモリ使用量はかなり低くなります。どうしたの?

4

2 に答える 2

1

コードを見ると、NULL 以外の呼び出しdeleteまたは以前に割り当て解除されたポインターが悪いことであるという事実により、メモリリークよりもセグメンテーション違反が発生します。delete[]また、投稿したものはコンパイルされないため、これが実際のコードであるとは思いません。

ポインターの場合はdelete、後で常に NULL に設定します。同様に NULL に初期化することをお勧めします。deleteコードを修正して、以前に割り当て解除されたポインターを呼び出さないようにしましょう。また、ポインターを NULL に初期化しましょう。

メモリの誤用は、次のコード行に起因する可能性があります。

Length += 250;
T* old = Items; 
Items = new T[Length + 250];

Length を 250 増やしてから、Length+250 の要素をさらに割り当てていることに注意してください。それも直しましょう。

template<class T> 
class Test 
{
public:
    int Size;
    int Length;
    T* Items; 

    Test() : Size(0), Length(0), Items(NULL){}

    ~Test() {
       if (Items != NULL)
          delete [] Items; 
    }

    void Append(const T& newItem) 
    {
        if (Size + 1 >= Length)
        {   
           Length += 250;
           T* old = Items; 
           Items = new T[Length]; 
           for (int i = 0; i < Size; i++) 
              Items[i] = old[i];
           delete [] old;
           old = NULL;
        }

        Items[Size] = newItem;  
        Size++;
    } 
};

int main(){
    Test<int> test;
    for (int i = 0; i < 500000; i++)
       test.Append(i);
}
于 2013-10-30T17:02:36.043 に答える