0

これらのシナリオがあり、メモリを正しく管理しているかどうかを知りたいです。実行可能ファイルを起動するときにタスク マネージャーでメモリの消費量を監視し、メモリが初期量に戻っていないことを確認します。これにより、必要な場所でメモリをクリアしていないのではないかと疑うようになります。したがって、この最初のケースでは、動的配列に新しい要素を追加する関数があります。

struct Color {
    int R;
    int G;
    int B;
}

int TotalColors;
Color* Rainbow;

void AddColor(Color NewColor) {
    // So, I create a new array of size TotalColors+1
    Color* NewRainbow = new Color[TotalColors+1];
    // Now I add the existing elements
    for (int i=0; i<TotalColors; i++) {
        NewRainbow[i] = Rainbow[i];
    }
    // And lastly, I add the new element
    NewRainbow[TotalColors] = NewColor;
    // Now, I assign the NewRainbow to Rainbow (I don't know if it's correct)
    Rainbow = NewRainbow;
}

では、この場合、私が何かを見逃していると思いますか? これは機能していますが、未使用のものをメモリから確実に削除したいと考えています。次のような要素を削除する関数もあります。

void RemoveColor(Color Removable) {
    // Again, I create a new array of size TotalColors-1
    Color* NewRainbow = new Color[TotalColors-1];
    // I scan the list and add only those elements which are not 'Removable'
    for (int i=0; i<TotalColors; i++) {
        // Let's suppose that Removable exists in the list
        if (Rainbow[i].R != Removable.R && Raibow[i].G != Removable.G && ... {
            NewRainbow [i] = Rainbow[i];
        }
    }
    // Again, the same operation as above
    NewRainbow[TotalColors] = NewColor;
    Rainbow = NewRainbow;
}

この場合、Rainbow[Removable]、つまり削除される配列の要素がどうなるかわかりません。そして最後のケースはこれで、要素のポインターを配列から関数に送信しようとしています。

Color* GetColor(int Index) {
    Color* FoundColor;
    // Scan the array
    for (int i=0; i<TotalColors; i++) {
        if (i == Index) FoundColor = &Rainbow[i];
    }
    return FoundColor;
}

// And I use it like this
void ChangeColor(int Index) {
    Color* Changeable;
    Changeable = GetColor(Index);
    SetRGB(Changeable, 100, 100, 100);
}

// And this is what changes the value
void SetRGB(Color* OldRGB, int R, int G, int B) {
    (*oldRGB).R = R;
    (*oldRGB).G = G;
    (*oldRGB).B = B;
}

で、これです。したがって、これは機能しますが、非常に多くのポインターで何かを削除するのを忘れなかったかどうかはわかりません。たとえばRemoveColor、メモリが変更されていない場合 (一部のバイトは違いがない可能性があります)、何かを見逃していないか専門家の目で教えてもらいたいだけです。ありがとう!

4

2 に答える 2

3

最初の関数AddColor()では、以前に割り当てられたメモリを削除していません。

Rainbow = NewRainbow; // leaking the memory Rainbow was previously pointing to.

その最後の行を次のように変更します。

delete[] Rainbow;
Rainbow = NewRainbow;

と同じことRemoveColor()

演算子を使用するときはいつでもnew、対応するdelete. また、あなたの場合のように配列を割り当てるnew[]場合は、対応するdelete[].

于 2013-03-29T14:39:48.800 に答える
1

ポインターを削除するのを忘れていないか心配しないために、プレーン ポインターを使用しないでください。代わりに、次のようなスマート ポインターを使用します。

std::shared_ptr
std::unique_ptr
etc.

または、C++11 をまだ持っていない場合は、

boost::shared_ptr
boost::scoped_ptr

スマート ポインターの詳細については、ウィキペディアと特定のドキュメントを参照してください。

于 2013-03-29T14:39:14.810 に答える