0
  struct Package_Node
    {
        int bar_code;
        float package_weight;
        Package_Node *next_packaged;
    };

    struct Key_Node
    {
        int key;
        Package_Node *next_package;
    };        

   for(int i=0; i<3; i++)
            {
                if(keyMain[i].next_package==NULL)
                {
                    continue;
                }

                if(keyMain[i].next_package!=NULL)
                {
                    nPointer3=keyMain[i].next_package;
                    nPointer4=keyMain[i].next_package;
                    while(nPointer3)
                    {
                        nPointer4=nPointer4->next_packaged;
                        delete[] nPointer3;
                        nPointer3=nPointer4;
                    }
                }
            }

keyMain指定された構造体によって記述される配列key_node

キーメイン自体は動的配列ですが、コードのために静的配列であることを示しました。

配列の長さが3インデックスで0,1,2、各インデックスに個別のリンクリストが含まれているとします。現在、各リンクリストを削除しようとしていますが、削除されているものと削除されていないものがあるようです。

これはどのように修正できますか?

4

3 に答える 3

1

ここで何が間違っているのですか?1つは、手動でメモリを管理していることです。

#include <memory>

struct Package_Node
{
  int bar_code;
  float package_weight;
  std::unique_ptr<Package_Node> next_packaged;
};

struct Key_Node
{
  int key;
  std::unique_ptr<Package_Node> next_package;
};

にポインタを格納するにはunique_ptr、を使用しますreset(new Package_Node())。の代わりにdelete、を呼び出しますreset()。が削除されると、が指すものはunique_ptrすべて自動的に削除unique_ptrされます。

これはC++11です。C++03では、、std::tr1::unique_ptrまたはを使用できますboost::unique_ptrが、移動セマンティクスを使用しないunique_ptrと、使用するのがより危険になります。


上記を実行すると、コードが大幅に短くなり、リンクリスト全体の割り当てを解除するのは.reset()、最初のノードへのスマートポインターの問題です。それ以外はすべて、自動的に消去されます。

ただし、これを行う気がない場合があります。だから私はあなたのコードの他のいくつかの問題を攻撃します。

変数名は値の使用法を反映していません。 nPointer4恐ろしい変数名です。PointerToDeleteその目的が何であるかを文書化してみてください。さらに、初期化の時点でポインタを宣言し、使用前または使用後にポインタをぶらぶらさせるのではなく、無効になった瞬間にポインタをクリアする必要があります。(変数を再利用してもボーナスポイントは得られません)。

このループを見てください:

            nPointer3=keyMain[i].next_package;
            nPointer4=keyMain[i].next_package;
            while(nPointer3)
            {
                nPointer4=nPointer4->next_packaged;
                delete[] nPointer3;
                nPointer3=nPointer4;
            }

の先頭で同じデータを保持する必要があることに注意しnPointer3てください。なぜ両方が存在するのでしょうか。次のように書き直すことで、状態を半分にすることができます。nPointer4while

            Package_Node* ptrToDelete=keyMain[i].next_package;
            while(ptrToDelete)
            {
                Package_Node* nextPtr = ptrToDelete->next_packaged;
                delete ptrToDelete;
                ptrToDelete = nextPtr;
            }

ptrToDelete初期化された瞬間にのみ存在することに注意してください。

nextPtr可能な限り短時間で存在し、その後範囲外になることに注意してください。また、初期化された後にのみ存在します。

次に、問題を実際に示すコンパイルコードを常に投稿してください。上記のコードは、問題とはまったく関係のない理由でコンパイルされません。また、心を読むことは、人々に求めるべきことではありません。

何が悪いのかわからないのですが、何が重要か、何が重要でないかをどうやって知るのでしょうか。簡単:コンパイラに理解させてください。あなたが抱えている問題を示す簡単な例を作成し、それをコンパイルし、問題がまだ発生することをテストしてから、それを投稿してください。

問題が発生する代わりに、パーツを削除して短くし、問題が発生する場合と発生しない場合がある非コンパイルコードを投稿し、他の人があなたの心を読んでくれることを期待します。

の使用struct Package_Node*は完全に不要です-Package_Node*より短く、(いくつかの極端なコーナーケースを除いて)まったく同じことを行います。

スマートポインタを使用しない場合でもstruct、ポインタを所有しているaはデストラクタでそれを破棄する必要があり、ポインタを所有していない場合は他の何かが必要です。 RAIIはあなたの友達です。ポインタを所有するaを作成するときは、3つのルールに従うことを忘れないでください。struct

于 2013-03-18T15:25:57.987 に答える
1

コメントで、nPointer3 メモリは「new Package_Node」を介して割り当てられると述べたので、「delete[] nPointer3;」という行 読む必要があります:

delete nPointer3;
nPointer3 = NULL;  // recommended (mentioned in another answer)

あなたが説明する動作は、特異な new を介して割り当てられた nPointer3 メモリを解放しようとする際の未定義の動作に起因する可能性があります。配列 new 演算子 "new[]" (例: new Package_Node[16]) によって割り当てられたメモリのみが、"delete []" で解放されます。

于 2013-03-18T17:00:03.380 に答える
1

削除されたかどうかを確認する方法がわかりません。メモリの割り当てを解除すると、そのメモリは再利用でき、それ以上アクセスすることはできなくなります。実行時エラーが発生しない限り、誰もあなたを止めることはありませんが、そのメモリの内容は割り当て解除によって変更されません。
特定のオブジェクトの割り当てが解除されたことを調べてもわかりません。

あなたの問題は、完了時に設定keyMain[i].next_packageするのを忘れたNULLことだと思います。

for(int i = 0; i < 3; i++)
{
    if (keyMain[i].next_package != NULL)
    {
        Package_Node* current = keyMain[i].next_package;
        Package_Node* next = 0;
        while (current)
        {
            next = current->next_package;
            // No "[]" since you're apparently not allocating with "[]"
            delete current;
            current = next;
        }
        keyMain[i].next_package = NULL;
    }
}
于 2013-03-18T16:05:36.943 に答える