1
#include <iostream>
#include "Student.h"
#include "SortedList.h"

using namespace std;

#define BOUNDS 100

int main() {

    SortedList *list = new SortedList();  // points to the sorted list object
    Student *create[BOUNDS];  // array to hold 100 student objects
    int num = 100000;   // holds different ID numbers

    // fills an array with 100 students of various ID numbers
    for (int i = 0; i < BOUNDS; i++) {
        create[i] = new Student(num);
        num += 10;
    }

    // insert all students into the sorted list
    for (int i = 0; i < BOUNDS; i++)
    list->insert(create[i]);

    // removes each student from the list
    num = 100000;
    for (int i = 0; i < BOUNDS; i++) {
    list->remove(num);
    num += 10;
    }

    delete list;
    return 0;
}

前のコードでセグ フォールトが発生しています。これがなぜなのか、またはそれを修正する方法についての洞察をいただければ幸いです。セグフォルトは間違いなくdelete list;回線が原因

更新 1: これが私の SortedList デストラクタです

/*
 * Destructs this sorted list object
 */
SortedList::~SortedList() {
    freeList(head);
}

/*
 * Traverses throught the linked list and deallocates each node
 */
void SortedList::freeList(Listnode *L) {
    Listnode *tmp = L;  //holds the node to be deleted

    //traverses the list
    while (tmp != NULL) {
        Listnode *next = tmp->next; //holds the value of the next node

    //delete previous node
    delete tmp->student;
    delete tmp->next;
    delete tmp;

    //sets the next node to the node to be deleted
    tmp = next;
    }
    //delete header node
    delete L;
}
4

3 に答える 3

4

まあ、私たちは見ることができませんSortedListまたはStudent、問題はそれらのいずれかにあると思います. num作成ループの後、元の値にリセットされることはありません。これは、ほとんどの呼び出しremoveに no に属する ID が渡されることを意味しStudentます。おそらくそのケースは失敗します。insertまたは、単にメソッドまたはremoveメソッド、またはコンストラクターまたはデストラクタにバグがあるだけかもしれません。それは完全に宙に浮いています。

編集:他の人が指摘したように、そのデストラクタは削除された後にポインタを使用します。それがエラーの唯一の原因である可能性もあれば、まだ確認していないコードが他にもある可能性もあります。

于 2012-04-12T02:42:21.247 に答える
2

freelist()、を削除tmp->nextしてから設定しtmp = tmp->nextます。現在tmp、無効なポインタがあります。メンバーにアクセスする前にポインターを解放しないように、コードを再構築する必要があります。

私は彼らのために人々の宿題をするのは嫌いですが、これが私の解決策です:

/*
 * Traverses throught the linked list and deallocates each node
 */
void SortedList::freeList(Listnode *L) {
    if(L == NULL) return;
    freeList(L->next);
    delete L->student;
    delete L;
}

これは削除にO(n)スタックスペースを使用しますが、個人的にはループよりもはるかに明確だと思います。の呼び出しを削除することで、ソリューションを「正常に機能する」ように調整できますdelete tmp->next

于 2012-04-12T02:54:55.237 に答える
1
 // removes each student from the list
    for (int i = 0; i < BOUNDS; i++) {
    list->remove(num);
    num += 10;
    }

面白そうです...これは正確にどのように機能しますか? コードのこの時点で num が 100000 + BOUNDS*10 の場合 (作成する生徒ごとに 10 を追加した後は決して変更されないため)。削除呼び出しを行うたびに、ID によって生徒が削除されるわけではありません (呼び出される ID は 100000 + BOUNDS*10 + i*10 であるため)。ID でそれらを削除する意図があったため、削除ループを実行する前に num を 100000 にリセットすることを検討する必要があります。

これが seg-fault を引き起こす可能性があることを明確にするために、削除関数に適切な境界チェックがない場合、削除する ID を探してメモリから外れる可能性があります。

デストラクタの質問で更新:

void SortedList::freeList(Listnode *L) {
    Listnode *tmp = L;  //holds the node to be deleted

    //traverses the list
    while (tmp != NULL) {
        Listnode *next = tmp->next; //holds the value of the next node

    //delete previous node
    delete tmp->student;
    delete tmp->next;
    delete tmp;

    //sets the next node to the node to be deleted
    //**********
    //Check here, you deleted next, but the assigned it to temp.  Tmp isn't null, but           
    //it is however, no longer your memory (since you deleted it)
    //**********
    tmp = next;
    }
    //delete header node
    delete L;
}
于 2012-04-12T02:47:37.607 に答える