2015-11-13 3 views
-2
==2630== Conditional jump or move depends on uninitialised value(s) 
==2630== at 0x4E82D71: vfprintf (in /usr/lib64/libc-2.21.so) 
==2630== by 0x4E88E78: printf (in /usr/lib64/libc-2.21.so) 
==2630== by 0x400C0C: searchWord (T9.c:91) 
==2630== by 0x400A0A: main (T9.c:40) 

==2114== Uninitialised value was created by a heap allocation 
==2114== at 0x4C28C50: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2114== by 0x400FD1: newStr (trie_node.c:125) 
==2114== by 0x400F8C: create_trie (trie_node.c:117) 
==2114== by 0x4009D5: main (T9.c:37) 

У меня есть сообщение об ошибке выше, бегая следящая функция в valgrind. Я уверен, что инициализировал переменную. Вот код структуры:Неинициализированное значение от valgrind

struct wordList* newStr(char* text) { 
    char* word; 
    struct wordList* tmp = (struct wordList*)malloc(sizeof(struct wordList)); 
    word = (char *)malloc(sizeof(char) * strlen(text) + 1); 
    strncpy(word, text, strlen(text)); 
    tmp->str = word; 
    tmp->next = NULL; 
    return tmp; 
} 

И коды вокруг T9.c линии 91:

struct wordList* cur; 
if (cur && invalid == 0 && flag == 0) { 
    printf("\t\'%s\'\n", cur->str); 
} 

Обновление:

Я модифицирование strncpy линии от

strncpy(word, text, strlen(text)); 

до

word = strncpy(word, text, strlen(text)); 

Это решило неинициализированную проблему, однако я получил новое сообщение об ошибке, что я не понимаю:

==3245== Invalid read of size 1 
==3245== at 0x4E82D71: vfprintf (in /usr/lib64/libc-2.21.so) 
==3245== by 0x4E88E78: printf (in /usr/lib64/libc-2.21.so) 
==3245== by 0x400C0C: searchWord (T9.c:91) 
==3245== by 0x400A0A: main (T9.c:40) 
==3245== Address 0x51f7d45 is 0 bytes after a block of size 5 alloc'd 
==3245== at 0x4C28C50: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==3245== by 0x400FC1: newStr (trie_node.c:124) 
==3245== by 0x400F80: create_trie (trie_node.c:117) 
==3245== by 0x4009D5: main (T9.c:37) 
+0

Что такое значение 'text', хотя? – Evert

+0

Вы можете оставить 'sizeof (char)', так как это будет 1, но если вы хотите быть явным, поместите круглые скобки вокруг 'strlen (text) + 1'. Кроме того, не бросайте возвращаемое значение malloc: 'void *' сам найдет свой путь к вашему 'char * word'. – Evert

+0

Пожалуйста, разместите код для его удаления и удалите его. –

ответ

3

мне нужно видеть больше кода, но пока я не уверен, что это именно то, что Valgrind жалуется о, ваш код имеет большую ошибку в нем:

strncpy(word, text, strlen(text)); 

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

Также обязательное предупреждение о прекращении литья возвращаемого значения malloc.

+0

Я обновил проблему больше –

+0

Null прекратить вашу строку. Я уже упоминал об этом, пожалуйста, прочитайте ответ. – Blindy

+2

В C нет функции, называемой 'strdup', она нестандартная. Поэтому нет причин быть самоуверенным в этом вопросе. – Lundin

0

Вы должны посмотреть полную ошибку (не только вторую). Как правило, вы должны читать ошибки сверху донизу, поскольку последующие ошибки могут быть следствием первого (или объяснения первого). Второе сообщение просто сообщает вам, что память, выделенная malloc, не инициализирована, что как и ожидалось - это всего лишь первоочередная задача для первого.

Ошибка возникает, когда вы используете выделенное пространство, не заполняя его чем-то полезным. Ошибка заключается в недавно опубликованном коде, блок, на который указывает cur->str, вероятно, не инициализирован.

Ошибка в том, что вы используете strncpy. Он будет копировать только strlen(text) байт и тем самым пропускает нулевой ограничитель. У вас есть место для него, но оно не копируется, поэтому последний байт выделенного буфера не инициализируется (ошибка возникает, когда vfprintf выполняет итерацию по строке и достигает байта, где должен быть нулевой ограничитель).

Чтобы было ясно, что такое strncpy(dst, src, cnt). Он копирует не более cnt байт (включая нулевой ограничитель), если строка src, включая нулевой ограничитель, не превышает cnt байт, она копирует полную строку. В противном случае он копирует только первые cnt байт строки и не null завершает dst.

+0

Кто-нибудь хочет сказать, почему он отказался? – skyking

+0

cur-> str инициализируется в методе newStr –

+0

@Big_tboy Я имел в виду, что данные, на которые указывает 'cur-> str', не полностью инициализированы. – skyking

Смежные вопросы