Неинициализированная стоимость была создана выделением "кучи"

Я преследовал эту ошибку вокруг, и я просто не получаю ее. Я забыл некоторый основной C или что-то?

==28357== Conditional jump or move depends on uninitialised value(s)
==28357==    at 0x4C261E8: strlen (mc_replace_strmem.c:275)
==28357==    by 0x4E9280A: puts (ioputs.c:36)
==28357==    by 0x400C21: handlePath (myshell.c:105)
==28357==    by 0x400B17: handleInput (myshell.c:69)
==28357==    by 0x400AAD: acceptInput (myshell.c:60)
==28357==    by 0x4009CF: main (myshell.c:33)
==28357==  Uninitialised value was created by a heap allocation
==28357==    at 0x4C25153: malloc (vg_replace_malloc.c:195)
==28357==    by 0x400BDE: handlePath (myshell.c:99)
==28357==    by 0x400B17: handleInput (myshell.c:69)
==28357==    by 0x400AAD: acceptInput (myshell.c:60)
==28357==    by 0x4009CF: main (myshell.c:33)
==28357==

(095) void handlePath(char *input) {
(096)     if(DEBUG_ON) { printf("%s%s\n", "DEBUG_HANDLEPATH: ", input); }
(097)
(098)     char *inputCopy = NULL;
(099)     inputCopy = (char *)malloc((strlen(input)+1)*sizeof(char));
(100)
(101)     if(inputCopy==NULL) {
(102)         die("malloc() failed in handlePath()");
(103)     }
(104)     strncpy(inputCopy, input, strlen(input)*sizeof(char));
(105)     printf("%s\n", inputCopy);
(106)     free(inputCopy);
(107)     return;
(108) }

Строка 96 печати параметр "символ *вход" очень хорошо (DEBUG_ON == 1), но намечают 105 слюны valgrind ошибки (это действительно печатает очень хорошо в консоли). "символ *вход" происходит из getline (), захват строки входа, и в случае этой функции будет чем-то как "путь/test/path" без кавычек. Я могу распечатать и управлять им очень хорошо в предыдущих функциях. Что является неинициализированным о "символе *inputCopy"? Какие-либо идеи? Заранее спасибо!

13
задан yavoh 30 January 2010 в 06:08
поделиться

3 ответа

У вас есть две ошибки в строке 104,

strncpy(inputCopy, input, strlen(input)*sizeof(char));

Вам нужно дать strncpy место для завершающего нуля, поэтому оно должно быть strlen (input) +1 strncpy не гарантировано оставить выходной буфер завершенным с нулевым завершением, что кажется ошибкой в ​​strncpy, но это не так. Он был разработан, чтобы работать именно так. Strncpy был разработан для копирования строки в выходной буфер, а затем заполнить оставшуюся часть буфера нулями . На самом деле он не разработан как «безопасный strcpy»

Другая ваша ошибка заключается в том, что strncpy принимает количество символов , а не количество байтов, поэтому умножать на sizeof (char) некорректно. . Поскольку sizeof (char) == 1, это на самом деле не вызывает проблем, но это все еще неправильное намерение.

Вы правильно умножили на sizeof (char) в malloc в строке 99, поскольку malloc требует счетчика байтов.

13
ответ дан 1 December 2019 в 22:57
поделиться

Я полагаю, что ваша strncpy не помещает прерывающий нулевой символ в конец строки, поэтому printf запускает конец выделенной памяти.

3
ответ дан 1 December 2019 в 22:57
поделиться

strncpy не ставит прерывающий 0 символ, так как он копирует максимум N символов (где N - это 3 параметра). Так как вы указали длину и не включили +1 для оканчивающегося 0 символа, он не был добавлен.

Таким образом, если предположить, что у вас буфер из N байт, то правильное использование strncpy - это:

strncpy(dest, src, N - 1);
dest[N - 1] = '\0';

strncpy - странная функция. Кроме того, что она не обещает записывать завершающий 0, она всегда будет записывать в буфер назначения ровно N символов. Если src меньше N, то strncpy на самом деле займет время, чтобы заполнить весь оставшийся буфер 0.

4
ответ дан 1 December 2019 в 22:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: