2017-09-11 31 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

歡迎堆棧溢出。請儘快閱讀[關於]和[問]頁面。更迫切的是,我們要睡覺看MCVE中的調用代碼([MCVE])。我們無法從這段代碼中發現哪裏出了問題。 –

+1

您不會顯示節點結構中的「x」元素是數組還是指針。如果它是一個數組,你會溢出嗎?如果它是一個指針,則在複製之前不會分配任何空間。 –

+0

爲了更加清晰,我更新了我的問題。請你再看一遍? –

回答

3

這是因爲你正在傳遞一個字符作爲一個字符指針(即一個字符串) 。 更改

char test_var = 'k'; 

char *test_var = "k"; 

並更改呼叫

add_to_list(newList, &test_var) 

add_to_list(newList, test_var) 
+0

好的答案。很高興能夠解釋爲什麼會發生這種情況。它發生的原因是因爲'strcpy(new_node-> x,item);'是用單個字符調用的,後面可能不會有空字符。因此,它會讀取該字母,然後繼續讀取*隨機存儲器*,直到找到0。 – Addison

+3

除此之外,還有更多。即使有這種變化,strcpy也是完全錯誤的。沒有內存分配給'x'指針指向'strcpy'調用之前。 OP代碼,即使有這種變化,也會調用* undefined *行爲。 – WhozCraig

0

對本聲明:

strcpy(new_node->x, item); 

'x'字段是未初始化的指針。因此使用該指針指向目標區域是未定義的行爲。

寫入未初始化指針指向的位置可能會導致seg故障事件。

AND是數據損壞的原因。你只是幸運的一個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 
相關問題