【问题标题】:Uninitialised value was created by a heap allocation未初始化的值是由堆分配创建的
【发布时间】:2011-01-11 03:24:51
【问题描述】:

我一直在寻找这个错误,但我就是不明白。我是否忘记了一些基本的 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”未初始化?有任何想法吗?提前致谢!

【问题讨论】:

    标签: c pointers malloc valgrind strncpy


    【解决方案1】:

    你在第 104 行有两个错误,

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

    你需要给 strncpy 空间给终止的 null,所以它应该是strlen(input)+1 strncpy 不能保证让输出缓冲区 null 终止,这似乎是 strncpy 中的一个错误,但事实并非如此。它旨在以这种方式工作。 strncpy 的设计目的是将字符串复制到输出缓冲区中,然后用零填充缓冲区的其余部分。它并不是真正设计为“安全 strcpy”

    您的另一个错误是 strncpy 采用 字符 计数而不是字节计数,因此乘以 sizeof(char). 是不正确的。由于 sizeof(char) == 1,这实际上并没有引起问题,但它仍然是错误的意图。

    在第 99 行的 malloc 中乘以 sizeof(char) 是正确的,因为 malloc 需要字节数。

    【讨论】:

    • 傻我!一个严重的 RTFM 案例就我而言。谢谢!这很好地解决了它。
    • sizeof(char)==1 根据定义,但明确无害。
    • @ephemient:同意,虽然我会写 sizeof(inputCopy[0]) 而不是 sizeof(char)。
    • @ephemient:期望这实际上与将1 * 放在变量前面相同:无用且令人困惑。我认为最好保持混乱。
    • 好收获。此外,无论如何 strncpy 可能应该只是 strcpy。
    【解决方案2】:

    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 填充整个缓冲区的其余部分。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2021-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多