2010-09-05 90 views
0

當我使用valgrind時,我在我的代碼中反覆收到以下錯誤。我不太確定這些是什麼意思,我無法確定未初始化的值。Valgrind /內存錯誤

==16795== Conditional jump or move depends on uninitialised value(s) 
==16795== at 0x4A06E8A: strcmp (mc_replace_strmem.c:412) 
==16795== by 0x4009C7: dictionary_add (libdictionary.c:44) 
==16795== by 0x40061B: main (part2.c:28) 
==16795== 
==16795== Invalid write of size 1 
==16795== at 0x4A082E7: strcpy (mc_replace_strmem.c:303) 
==16795== by 0x400AA8: dictionary_add (libdictionary.c:57) 
==16795== by 0x40061B: main (part2.c:28) 
==16795== Address 0x4c361a3 is 0 bytes after a block of size 3 alloc'd 
==16795== at 0x4A05E1C: malloc (vg_replace_malloc.c:195) 
==16795== by 0x400931: node_newnode (libdictionary.c:28) 
==16795== by 0x400A8C: dictionary_add (libdictionary.c:54) 
==16795== by 0x40061B: main (part2.c:28) 

我在創建一個鏈表數據結構,這些函數在給出這個內存錯誤時被調用。

//下面是一個節點和字典數據結構的結構。

typedef struct node 
{ 
char* key; 
char* value; 
struct node* next; 
}node; 


typedef struct _dictionary_t 
{ 
node* head; 

} dictionary_t; 

//首先//一個新的節點是使用node_init方法創建一個新的字典創建

void dictionary_init(dictionary_t *d) 
{ 
d->head = NULL; 
d->head = malloc(sizeof(node)); 
node_init(d->head); 
} 

void node_init(node *n) 
{ 
n->key = NULL; 
n->value =NULL; 

n->key = malloc(sizeof(char)); 
n->value = malloc(sizeof(char)); 
n->next = NULL; 
} 

//該新節點方法(當我們增加新的術語)的前一個是專門爲在創建所述結構的開始創建一個前哨原始初始化後使用。

void node_newnode(node *n, int x, int y) 
{ 
n->key = NULL; 
n->value = NULL; 

n->key = malloc(x*sizeof(char)); 
n->value = malloc(y*sizeof(char)); 
n->next = NULL; 
} 

//這個函數也被調用來在這種情況下添加「key」和「value」作爲一對。

int dictionary_add(dictionary_t *d, const char *key, const char *value) 
{ 
node *current; 
current = d->head; 
if(strcmp(current->key,key)==0) 
     return -1; 
while(current->next != NULL){ 
     current=current->next; 
     if(strcmp(current->key,key)==0) 
       return -1; 
} 
     current->next = NULL; 
     current->next = malloc(sizeof(node)); 

     node_newnode(current->next,strlen(key),strlen(value)); 

     current = current->next; 
     strcpy((current->key), key); 
     strcpy((current->value),value); 
     return 0; 
} 

任何人有任何想法,爲什麼我得到這些錯誤。迄今爲止,主要的方法只創建了一個字典並稱爲add函數。 Valgrind在8個函數調用過程中報告了超過38個上下文中的45多個錯誤。我認爲這些可能是我重複犯下的小錯誤。

我現在也得到這個函數相同的錯誤。甲的valgrind --track-起源= yes命令它的蹤跡的堆棧分配在下面的函數:

int dictionary_parse(dictionary_t *d, char *key_value) 
{ 
char* colon; 
char* space; 
colon = key_value; 
space = key_value; 

space++; 

int key_length = -1; //Default key length to check for failure 

int i=0; 
int j=0; // Loop variables 
int k=0; 

int length = strlen(key_value); 

for(i=0;i<length-2;i++){ 
     if(*colon == ':' && *space == ' '){ 
       key_length = i; 
       break; 
     } 
     colon++; 
     space++; 
} 

if(key_length == -1 || key_length == 0) 
     return -1; 

int value_length = length-2-key_length; 

colon = key_value; 


char key_word[key_length]; 
key_word[0] = '\0'; 
char value_word[value_length]; 
value_word[0] = '\0'; 

for(j=0;j<key_length;j++){ 
key_word[j] = *colon; 
colon++; 
} 

space++; 

for(k=0; k<value_length;k++){ 
value_word[k] = *space; 
space++; 
} 


char* finalkey[key_length]; 
strcpy((char*)finalkey,key_word); 
char* finalvalue[value_length]; 
strcpy((char*)finalvalue,value_word); 

dictionary_add(d,(char*)finalkey,(char*)finalvalue);  

return 0; 

} 

謝謝, -newprogrammer

+1

順便說一句,爲什麼在分配'malloc'返回的指針之前立即爲變量賦值'NULL'?這沒有必要。 – 2010-09-05 06:46:51

回答

10

第一錯誤(「條件跳轉或移動取決於未初始化值(s)「)是因爲current->key指向的字符從未初始化過。您在node_init()中爲它分配了一個字節,但您從未真正將該字節設置爲任何內容。如果你想head節點的key表現得像一個空字符串,改變node_init()這樣的:

n->key = malloc(sizeof(char)); 
n->key[0] = '\0'; 

第二個錯誤(「大小1的無效寫」)是因爲你node_newnode()功能分配比減去1個字節需要的字符串。 strlen(key)計算字符串中的實際字符數,但空終止符字符需要多一個字節。用途:

node_newnode(current->next,strlen(key) + 1,strlen(value) + 1); 

(但我個人只想通過keyvaluenode_newnode(),並將它做到既分配和strcpy())。

+0

感謝您的解釋! – gaussblurinc 2012-12-05 05:05:57