0

以下の構造体を使用して、学生のリンクリストを作成しようとしています。

struct student 
{
    int student_ID;
    char *student_name;
    struct course *courses_enrolled;
    Student *child;
};

//Insert student to the list with a given student pointer and the starting point
Student *insert_student(Student *child, Student *root)
{
    Student *temp = (Student*)malloc(sizeof(Student));
    //if there isn't a starting point, declare this as the start point
    if( root->student_name == NULL )
    {
        root->student_ID = child->student_ID;
        root->student_name = strdup(child->student_name;);
        root->child = NULL;
    }
    //if this student's name is before current node, replace node.
    else if( strcmp( child->student_name, root->student_name ) < 0 )
    {
        temp = root;
        root = child;
        child->child = temp;
    }
    //if this student's name is after current node, keep doing insert recursion
    else if( strcmp( child->student_name, root->student_name ) > 0 )
    {
        insert_student( child, root->child );
    }

    return root;
}

最初のルート挿入は常に正常に機能しますが、2 番目のルート挿入を追加しようとすると、insert_student への 2 回目の呼び出しの後にプログラムがセグ フォールトになります。比較で失敗する

if( root->student_name == NULL )

ルートの子ノード(ルート->子)にアクセスすることと関係があると思われますが、実際にはわかりません。

p/s: 割り当てを解除していないことはわかっています。別のライブラリを使用する必要があるため、これは一時的なものです。

更新: 余分なコードを削除しました。

4

3 に答える 3

1

この関数がどのように呼び出されるかがわからないため、正確な問題を見つけるのは少し困難です。確認したいことがいくつかあるようです。

関数に渡した と が実際に割り当てられ、ルートのすべてのフィールドが に設定され、その学生の名前が適切であるため、2 番目の分岐が発生しないchildと想定しています。その後、最初の挿入が機能します。rootNULL

しかし、2回目の挿入を行うとき。最初の句でroot->childに設定したものを渡しています。逆参照できないため(エラーをスローするなど) 、これはその後の失敗につながります。NULLifstrcmpNULLNULL->student_name

于 2012-09-30T19:50:58.793 に答える
0

insert_student を再帰的に呼び出すときは、渡す値がrootnull でないことを確認する必要があります。null の場合は、おそらく別のケースが必要です (最後に挿入するなど)。

私が気づいたことの 1 つは、割り当てられた の値を決して使用しないことですtemp。使用する前に常に未使用または廃棄tempされます。これはあなたが望むものではないと思います。

また、一般に、単語nextは構造体の代わりに使用され、パラメーターの子のchildようなものnewStudentまたは単に代わりに使用されます。student

于 2012-09-30T19:40:13.520 に答える
0
if( root->student_name == NULL )
{
    printf("Always here?\n");
    root->student_ID = child->student_ID;
    root->student_name = strdup(child->student_name);
    temp->student_ID = 0;
    temp->student_name = NULL;
    root->child = temp;
}

子ノードにアクセスする前に、子ノードの変数を NULL として実際に宣言する必要があることがわかりました。

于 2012-09-30T19:50:30.120 に答える