0

これは、同様の名前の質問の複製ではありません。これには、OOP と new および delete 呼び出しが含まれます。

リンクされたリストの後ろまで反復し、最後のノードのヒープに割り当てられたメモリを削除する関数を作成しようとしています。

これが私のコードです:

void LinkedList::delete_back(){
    if(head != NULL){
            ListNode *end = head;
            while(end->next != NULL)
                    end = end->next;
            delete end;
    }
    size--;
}

そして、ここに私のクラス定義があります:

class ListNode{

    public:
            Item data;
            ListNode *next;
};
class LinkedList{

    private:
            ListNode *head;
            int size;

    public:
            LinkedList();
            ~LinkedList(); 
            bool empty();
            void insert_front(Item i);
            void insert_back(Item i);
            void delete_front();
            void delete_back();
            void print();
};

Annddddd .....これが問題です。valgrind から次のようなエラー メッセージが大量に送信されます。サイズ 4 の無効な読み取りを示すものもあれば、サイズ 8 の無効な読み取りを示すものもあります。

==4385== Invalid read of size 4
==4385==    at 0x400CAA: LinkedList::print() (in /home/jon/jball2_lab06/linkedlist)
==4385==    by 0x400EDD: main (in /home/jon/jball2_lab06/linkedlist)
==4385==  Address 0x5a04f30 is 0 bytes inside a block of size 16 free'd
==4385==    at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4385==    by 0x400C5E: LinkedList::delete_back() (in /home/jon/jball2_lab06/linkedlist)
==4385==    by 0x400E99: main (in /home/jon/jball2_lab06/linkedlist) 

それが役に立ったら、残りのエラーを投稿しますが、必要がない限り、50行でスペースを4回押す気はありません。これが何であるか知っている人はいますか?私は何を間違っていますか?

更新 ----------------------- コードを次のように編集しました。

void LinkedList::delete_back(){
    if(head != NULL){
            ListNode *end = head;
            ListNode *prev_end;
            while(end->next != NULL){
                    prev_end = end;
                    end = end->next;
            }
            prev_end->next = NULL;
            if(end != NULL) delete end;
            size--;
    }
}

サイズ 8/4 の無効な読み取りエラーと無効な解放/削除エラーが増えています。

==5294== Invalid free() / delete / delete[] / realloc()
==5294==    at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

この:

==5294== Use of uninitialised value of size 8
==5294==    at 0x400C3D: LinkedList::delete_back() (in /home/jon/jball2_lab06/linkedlist)
==5294==    by 0x400EEC: main (in /home/jon/jball2_lab06/linkedlist)

使用しているテストコードは次のとおりです。

    for(Item i = 50; i < 100; i++){
            ll.insert_back(i);
            cout << "Inserted [" << i << "] in back.\n";
    }
    ll.print();
    for(int i = 0; i < 50; i++)
            ll.delete_back();
    cout << "Removed 50 elements from the back.\n";
    ll.print();

これは、最後の要素が delete_back() を使用してリストから削除されたときに発生します。

アップデート - - - - - - - - - - - - -

問題は、end->next が null の場合、while ループが実行されず、prev_end が初期化されないことでした。修正が実装された投稿された回答。

4

6 に答える 6

1

新しい終了ノードを null に設定していません。

例:

A->B->C->NULL

C を削除すると、B の次はダングリング ポインターになります

したがって、削除機能では、最後から 2 番目のノードに移動し、その次のノードを NULL に設定する必要があります。

C を削除した後の上記の例では、リストは次のようになります。

A->B->(ダングリング) の代わりに A->B->NULL

したがって、次の delete_back 操作で B を削除できます。

以下のようなことができます

void LinkedList::delete_back(){
if(head != NULL){
        ListNode *end = head;
        //This if block is for when only one element is left
        if(end->next == NULL)
         { delete end;
           end = NULL;
         }
        else
        while(end!= NULL)
        { 
               if(end->next) /// reach the second last element
                if(end->next->next==NULL)
                 {
                  delete end->next; //delete the last element
                  end->next=NULL; // set the next of second last element to NULL
                 }
               end=end->next;
        } 
  size--;
  }
  }
于 2013-10-11T20:03:01.950 に答える
0

このように動作するはずです

void del_rear()

{
  struct node *end, *last

 if (head->next != NULL) {

   *end=head;

while(end->next!=null){
*last=end;
 end=end->next;
  }
    free(end);
    last->next=null;
   }     
 else
   {

    pf("list is empty\n");
 }
} 
于 2015-10-23T15:10:44.207 に答える
0

すべての問題を修正しました。

コード:

void LinkedList::delete_back(){
    if(head != NULL){
            ListNode *end = head;
            if(end->next != NULL){
                    ListNode *prev_end;
                    while(end->next != NULL){
                            prev_end = end;
                            end = end->next;
                    }
                    prev_end->next = NULL;
                    delete end;
            }
            else {
                    delete head;
                    head = NULL;
            }
            size--;
    }
}
于 2013-10-13T19:37:35.390 に答える
0

最後に削除する最も簡単なコードは次のとおりです。

void DeleteAtLast(){
    node *temp=head;
    while(temp->next->next!=NULL){
        temp=temp->next;
    }
    temp-next=NULL;
}
于 2016-12-06T19:31:01.540 に答える