2010-09-05 1 views
4

Я создал связанный класс списка, но эта функция генерирует ошибки valgrind, говоря, что есть условный переход, основанный на неинициализированном значении этой функции. Я не совсем уверен, что мне нужно сделать, чтобы исправить это.Valgrind Uninitialized Values ​​(создание связанного списка данных struct)

По существу, существует класс узлов для связанного списка, и он выполняет итерацию по всем узлам, проверяя, соответствует ли ключевой параметр предварительно существующему узлу, и если он возвращает значение.

const char *dictionary_get(dictionary_t *d, const char *key) 
{ 

node* current; 
current = d->head; 
if(strcmp(current->key,key)==0) 
     return current->value; 
while(current->next != NULL){ 
     current = current->next; 
     if(current!=NULL && strcmp(current->key,key)==0) 
       return current->value; 
} 

     return NULL; 
}  

Любые идеи?


Я с VALGRIND пересматриваются отслеживания происхождения, и это выход:

==25042== Conditional jump or move depends on uninitialised value(s) 
==25042== at 0x4A06E6A: strcmp (mc_replace_strmem.c:412) 
==25042== by 0x400DD6: dictionary_get (libdictionary.c:143) 
==25042== by 0x400826: main (part2.c:84) 
==25042== Uninitialised value was created by a stack allocation 
==25042== at 0x400AE3: dictionary_parse (libdictionary.c:69) 
==25042== 
==25042== Conditional jump or move depends on uninitialised value(s) 
==25042== at 0x4A06E8A: strcmp (mc_replace_strmem.c:412) 
==25042== by 0x400DD6: dictionary_get (libdictionary.c:143) 
==25042== by 0x400826: main (part2.c:84) 
==25042== Uninitialised value was created by a stack allocation 
==25042== at 0x400AE3: dictionary_parse (libdictionary.c:69) 
==25042== 
==25042== Conditional jump or move depends on uninitialised value(s) 
==25042== at 0x400DD9: dictionary_get (libdictionary.c:143) 
==25042== by 0x400826: main (part2.c:84) 
==25042== Uninitialised value was created by a stack allocation 
==25042== at 0x400AE3: dictionary_parse (libdictionary.c:69) 

Похоже, это может приходить от dictionary_parse, поэтому я выложу эту функцию тоже.

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; 
} 
+0

Эй, пожалуйста, запустить Valgrind так же, как вы были, но и с '--track-originins = yes' и вставить результат в вопрос. Также вы можете использовать 'gdb' для проверки программы с помощью' --db-attach = yes' – alternative

+0

Какая строка находится в строке 69 в libdictionary.c? Какая строка - строка 84 в part2.c? – alternative

+0

84 in part2.c: s = dictionary_get (& dictionary, "e"); 69 в libdict.c: int dictionary_parse (dictionary_t * d, char * key_value) { – newprogrammer

ответ

-2

Если ваша программа работает правильно, не беспокойтесь об этих предупреждениях. Я видел предупреждение условного перехода на программы, которые в противном случае работают отлично. Вероятно, это связано с кодом сборки, сгенерированным компилятором и не связанным напрямую с вашим кодом.

+0

-1 Нет абсолютно никаких оснований предполагать, что это ложный позитив. Он должен быть проверен, потому что он может легко ввести ошибку позже. – alternative

+0

@mathepic: Я никогда не видел, чтобы это конкретное предупреждение вызывало проблему. Компиляторы могут делать странные вещи при оптимизации кода, и это, вероятно, будет побочным эффектом этого. – casablanca

+0

Обычно Valgrind запускается по неоптимизированному коду (-g -O0) – alternative

1

Линии как

char key_word[key_length]; 

выглядят весьма подозрительно.

Я не знаю, что вы делаете с ними дальше, но создайте временный массив переменной длины для вещей, которые должны быть постоянными дольше, чем вызов функции, кажется очень странным.

Кроме того, массив переменной длины не включает завершающий '\0'.

1

Вы не имеете нулевое завершение строк в key_word и value_word, и эта ошибка, по-видимому, распространяется. Этот цикл является проблемой:

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

Она копирует key_length символов в key_word, но ни один из этих скопированных символов не является нулевым терминатором. Вы можете решить эту проблему, добавив один дополнительный байт key_word:

char key_word[key_length + 1]; 

Затем, добавив это после for() цикла:

key_word[key_length] = '\0'; 

Там также нет необходимости создавать копии в finalkey и finalvalue (который во всяком случае, неправильный тип - вот почему вы в конечном итоге нуждаетесь во всех этих уродливых бросках). Так в целом это будет выглядеть следующим образом:

char key_word[key_length + 1]; 
char value_word[value_length + 1]; 

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

space++;  

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

dictionary_add(d, key_word, value_word); 

Действительно, хотя, вы должны упростить эту функцию, используя средства из string.h.Например, strstr() позволит вам искать ": " строку, которая отделяет ключ и значение, и memcpy() делает эквивалент этих for() петель:

int dictionary_parse(dictionary_t *d, char *key_value) 
{ 
    char *colon; 
    char *value; 
    int key_length = -1; //Default key length to check for failure 

    colon = strstr(key_value, ": "); 

    if (colon != NULL) { 
     key_length = colon - key_value; // Number of characters before the colon 
     value = colon + 2; // Value is portion of the string after ": " 
    } 

    if (key_length < 1) { 
     return -1; 
    } 

    char key_word[key_length + 1]; 
    memcpy(key_word, key_value, key_length); 
    key_word[key_length] = '\0'; 

    dictionary_add(d, key_word, value); 

    return 0; 
} 
Смежные вопросы