13

我一直在追逐这个错误,我就是不明白。我是否忘记了一些基本的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 行打印参数“char *input”就好了(DEBUG_ON==1),但第 105 行吐出了 valgrind 错误(它在控制台中打印得很好)。“char *input”源自获取一行输入的 getline(),在此函数的情况下,将类似于不带引号的“path /test/path”。我可以在前面的函数中很好地打印和操作它。什么是“char *inputCopy”未初始化?有任何想法吗?提前致谢!

4

3 回答 3

13

你在第 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需要字节数。

于 2010-01-30T06:17:57.150 回答
4

strncpy 不会放置终止 0 字符,因为它最多复制 N 个字符(其中 N 是 3 参数)。由于您指定了长度并且没有包括终止 0 的 +1,因此没有添加它。

所以假设你有一个 N 字节的缓冲区,正确使用 strncpy 是这样的:

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

strncpy 是一个奇怪的函数。除了不承诺写入终止的 0 外,它总是会准确地将 N 个字符写入目标缓冲区。如果 src 小于 N,strncpy 实际上会花时间用 0 填充整个缓冲区的其余部分。

于 2010-01-30T06:18:35.667 回答
3

我相信您strncpy没有在字符串末尾放置终止空字符,因此 printf 正在超出分配内存的末尾。

于 2010-01-30T06:13:02.667 回答