2017-09-11 8 views
0

私のリストの最初のノードに迷惑データがあるようです。これはなぜでしょうか?リンクリストの最初のノードに迷惑データがあるのはなぜですか?

これは私が使用している構造体の定義です。

typedef struct node { 
    char *x; 
    struct node *next; 
}node; 

typedef struct { 
    struct node *head; 
}list; 

// create_list()関数:ここ

list* create_list(){ 
    list *myList = malloc(sizeof(myList)); 
    myList->head = NULL; 
    if (myList->head != NULL){ 
     return NULL; 
    } 
    return myList; 
} 

がadd_to_list機能の実装である

int add_to_list(list* ll, char* item){ 

    node *current = ll->head; 
    node *new_node = malloc(sizeof(node)); 
    if (!new_node){ 
     fprintf(stderr, "error allocating mem.\n"); 
     return 1; 
    } 
    strcpy(new_node->x, item); 
    new_node->next = NULL; 
    if(ll->head == NULL){ 
     ll->head = new_node; 
     return 0; 
    }else{ 
     while(current->next){ 
     current = current->next; 
    } 
    current->next = new_node; 
    } 
    return 0; 
} 

これは(print_listです)。 funcntion

void print_list(list *ll){ 

    node *current = ll->head; 
    while(current){ 
     printf("%s\t\n",current->x); 
     current = current->next; 
    } 
} 

私はここにmain.cの中で関数を呼び出す私はそれをやっている方法です:

list *newList = create_list(); 

char test_var = 'k'; 

add_to_list(newList, &test_var); 

printf("printing whole list : \n"); 

print_list(newList); 
+2

ようこそ:それ以外の場合は

、のようなものを使用することをお勧め。まもなく、[About]と[Ask]ページをお読みください。もっと緊急に、私たちはMCVE([MCVE])で呼び出しコードを見て寝るつもりです。このコードから何がうまくいかないかはわかりません。 –

+1

ノード構造の 'x'要素が配列かポインタかを表示しません。それが配列の場合、オーバーフローする可能性がありますか?ポインタの場合は、コピーする前にスペースを割り当てないでください。 –

+0

私の質問がより明確になるように更新しました。もう一度見てもらえますか? –

答えて

3

あなたはchar型のポインタ(すなわち、文字列)として文字を渡しているので、それがあります。このステートメントに関する

add_to_list(newList, test_var) 
+0

良い答え。なぜこれが起こっているのかを正確に説明することはうれしいでしょう。その理由は、 'strcpy(new_node-> x、item);'がシングル文字で呼び出されたためで、おそらくそれの後ろにヌル文字はありません。したがって、それは手紙を読んでから0を見つけるまで*ランダムな記憶*を読んでいきます。 – Addison

+3

この答えだけではありません。その 'strcpy'は、この変更があっても完全に間違っています。 'strcpy'呼び出しの前に' x'ポインタが指すようにメモリは割り当てられません。 OPsコードは、この変更があっても*未定義*ビヘイビアを呼び出しています。 – WhozCraig

0

add_to_list(newList, &test_var) 

への呼び出しを

char *test_var = "k"; 

char test_var = 'k'; 

を変更し、変更 :

strcpy(new_node->x, item); 

「x」フィールドは、初期化されていないポインタです。したがって、そのポインタを使用して宛先領域を指すことは、未定義の動作です。

初期化されていないポインタポイントがどこに書き込まれると、segaultイベントが発生する可能性があります。

また、データが壊れている理由はこのためです。あなたの幸運なsegフォルトは発生せず、他のデータも破損していません。

データの最大長を知っている場合は、フィールド 'x'がポインタではなくcharの配列になるように構造体定義を変更できます。スタックオーバーフロー

new_node->x = strdup(data); 
if(!new_node->x) 
{ // then strdup() failed 
    perror("strdup failed"); 
    // call a cleanup function here 
    free(new_node); 
    exit(EXIT_FAILURE); 
} 

// implied else, strdup successful 
関連する問題