2017-05-24 1 views
0

私はリストを使ってこの単純なプログラムで作業していますが、ポインタを渡すのに悪い時があります。C - サブリンクされたリストを関数に渡す

のは、私が学生

typedef struct student{ 
    char lastname[50]; 
    int age; 
    int std_id; 
    struct student * next; 
    struct student * prev; 
}stdn; 

のための構造体を持っていると私は基本的に、私はクラスでこのリストを持っており、各クラスは、学生とサブリストを含むクラス

typedef struct class{ 
    char class_id[3]; 
    struct class * next; 
    struct class * prev; 
    struct student * stdn_list; 
}clss; 

のための別の構造体を持っているとしましょう。

ここでは、クラスリストを作成する関数があります。

void create_class_list(clss ** root, clss * node){ 
    clss * root_aux; 
    if(!(*root)){ 
     (*root) = node; 
    } 
    else{ 
     root_aux = (*root); 
     while(root_aux->next != NULL){ 
      root_aux = root_aux->next; 
     } 
     node->prev = root_aux; 
     root_aux->next = node; 
    } 
} 

私はクラスリストの各ノードにサブリストで作業する必要があるとき、私の問題があります。ここで

はサブリストを作成する担当の関数であり、それは

void assign_student(clss ** root, stdn * node, char * class_id){ 
     clss * root_aux; 
     stdn * stdn_aux; 
     root_aux = (*root); 

     while(root_aux != NULL){ 
      if(strcmp(root_aux->class_id,class_id) == 0) 
       break; 
      root_aux = root_aux->next; 
     } 
     if(root_aux != NULL){ 
      if(root_aux->stdn_list == NULL){ 
       root_aux->stdn_list = node; 
      } 
      else{ 
       stdn_aux = root_aux->stdn_list; 
       while(stdn_aux->next != NULL){ 
        stdn_aux = stdn_aux->next; 
       } 
       node->prev = stdn_aux; 
       stdn_aux->next = node; 
      } 
     } 
    } 

基本的にこの関数は特定のクラスを検索し、そのクラスに生徒を追加動作します。

私の問題は、生徒を削除したい場合、または、bubblesortのようなアルゴリズムを使ってリストをソートしたいときです。生徒を削除する関数の例です。

void delete_student(clss ** root, int stdn_id){ 
    clss * root_aux; 
    stdn * stdn_aux; 
    stdn * temp; 
    int deleted=0; 

    root_aux = (*root); 
    while(root_aux != NULL){ 
     stdn_aux = root_aux->stdn_list; 
     //try with root first// 
     if(stdn_aux->std_id == stdn_id){ 
      temp = stdn_aux; 
      stdn_aux = stdn_aux->next; 
      stdn_aux->prev = NULL; 
      free(temp); 
      deleted = 1; 
     } 
     //if the student isn't the root 
     if(deleted == 0){ 
      stdn_aux = stdn_aux->next; 
      while(stdn_aux != NULL){ 
       if(stdn_aux->std_id == stdn_id){ 
        temp = stdn_aux; 
        //link the prev element with the next element 
        stdn_aux->prev->next = stdn_aux->next; 
        //link the next element with the prev element 
        stdn_aux->next->prev = stdn_aux->prev; 
        stdn_aux = stdn_aux->next; 
        free(temp); 
        deleted = 1; 
        break; 
       } 
       stdn_aux = stdn_aux->next; 
      } 
     } 
     if(deleted == 1){ 
      break; 
     } 
     root_aux = root_aux->next; 
    } 
} 

リストから要素を削除しないと、私は関数へのポインタを渡すか、どのように私は最初の場所でリストを作成する方法で何かあるのかはわからないんのような機能がちょうど見えます。

+0

'stdn_aux-> next'はnullになります –

+0

[mcve]を作成してください。 MCVEには、さまざまなサンプル入力(すべての側面を示す)と望ましい出力が含まれている必要があります。 デバッグコードのヘルプをお探しの場合は、https://ericlippert.com/2014/03/05/how-to-debug-small-programs/を参照してください。 – Yunnosch

答えて

1

学生リストの先頭にある学生ノードを削除すると、現在指しているノードを削除するので、root_aux-> stdn_listに再割り当てする必要があります。それはあなたが学生ノードを削除していないことを教えてくれる理由です。

root_aux->stdn_list = stdn_aux->next; 

文がダンプコアからプログラムを防止するために、場合に包まれるべき処理に関する他の問題があります:あなたが学生のリストの処理を開始する前に

は、あなたが最初にそこにあることを確認する必要があります学生リストつまり、学生リスト(root_aux-> stdn_list - )を指すクラス変数がNULLでないことを確認します。

次の文を実行する前に、stdn_aux-> nextがNULLでないこと、つまり、削除するルートノードを超えるものがあることを確認してください。これは学生のリストの最後のノードであるため、stdn_aux->この割り当て

stdn_aux->next->prev = stdn_aux->prev; 

チェックは次のnullではない行う前に

stdn_aux = stdn_aux->next; 
stdn_aux->prev = NULL; 

関連する問題