我一直在追逐这个bug,我只是不明白。我忘记了一些基本的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”的未初始化是什么?有任何想法吗?提前谢谢!
答案 0 :(得分:13)
你在第104行有两个错误,
strncpy(inputCopy, input, strlen(input)*sizeof(char));
你需要为终止null赋予strncpy空间,所以它应该是strlen(input)+1
strncpy不保证将输出缓冲区空终止,这似乎是strncpy中的一个错误,但事实并非如此。它旨在以这种方式工作。 strncpy的目的是将字符串复制到输出缓冲区,然后用零填充缓冲区的其余部分。它实际上并不是设计为'safe strcpy'
你的另一个错误是strncpy将字符计算为字节数,因此乘以sizeof(char).
是不正确的。由于sizeof(char)== 1,这实际上不会导致问题,但仍然是错误的意图。
由于sizeof(char)
需要字节数,因此在第99行的malloc
中乘以malloc
是正确的。
答案 1 :(得分: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来填充缓冲区的其余部分。
答案 2 :(得分:3)
我相信你的strncpy
没有在字符串的末尾放置一个终止空字符,所以printf在分配的内存的末尾运行。