valgrind 对未初始化值的抱怨会是误报吗?

发布于 2024-11-15 12:48:15 字数 1001 浏览 1 评论 0原文

所以我一直在自学 C,并希望从一开始就学习如何正确管理内存并编写更好的代码,我一直在所有内容上运行 Valgrind。这帮助我解决了内存泄漏问题,但我似乎无法摆脱这种“条件跳转或移动取决于未初始化值/未初始化值是由堆分配创建”的情况,尽管我已经缩小了范围到这段代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()    
{  
    char* test = (char*) malloc(3);
    strncpy(test, "123", 2);
    printf("%s\n", test);
    free(test);
    return 0;
}

当我使用 ---track-origins=yes 运行 Valgrind 时,我得到以下输出:

==91702== Conditional jump or move depends on uninitialised value(s) 
==91702==    at 0x100011507: strlen (mc_replace_strmem.c:282)
==91702==    by 0x1000AA338: puts (in /usr/lib/libSystem.B.dylib)
==91702==    by 0x100000EFA: main (valgrind_test.c:10)
==91702==  Uninitialised value was created by a heap allocation
==91702==    at 0x100010345: malloc (vg_replace_malloc.c:236)
==91702==    by 0x100000EEA: main (valgrind_test.c:8)

这对我来说似乎是误报,但我对自己的能力不够有信心自己的知识就这样把它写掉。也许我分配错误或使用 strncpy 错误?我不知道。

提前致谢

So I've been teaching myself C, and in the hopes of learning how to properly manage memory from the beginning and write better code, I've been running Valgrind on everything. This has helped me with memory leaks, but I can't seem to get rid of this "Conditional jump or move depends on uninitialised value(s)/Uninitialised value was created by a heap allocation" situation, although I've narrowed it down to this block of code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()    
{  
    char* test = (char*) malloc(3);
    strncpy(test, "123", 2);
    printf("%s\n", test);
    free(test);
    return 0;
}

When I run Valgrind with ---track-origins=yes, I get this output:

==91702== Conditional jump or move depends on uninitialised value(s) 
==91702==    at 0x100011507: strlen (mc_replace_strmem.c:282)
==91702==    by 0x1000AA338: puts (in /usr/lib/libSystem.B.dylib)
==91702==    by 0x100000EFA: main (valgrind_test.c:10)
==91702==  Uninitialised value was created by a heap allocation
==91702==    at 0x100010345: malloc (vg_replace_malloc.c:236)
==91702==    by 0x100000EEA: main (valgrind_test.c:8)

This seems like a false positive to me, but I'm not confident enough in my own knowledge to write it off as such. Maybe I'm allocating wrong or using strncpy wrong? I'm not sure.

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橘味果▽酱 2024-11-22 12:48:15

不,这是损坏的代码。

您有一个包含 3 个未初始化字符的内存块。然后将 "12" 复制到其中,并且不要终止。当心strncpy()

我引用文档

strncpy()函数类似,只不过复制的src不超过n个字节。因此,如果 src 的前 n 个字节中没有空字节,则结果不会以空终止。

由于源的前 2 个字符内没有终止符,因此目标不会终止。

No, this is broken code.

You have a memory block with 3 uninitialized characters. Then you copy "12" into it, and don't terminate. Beware of strncpy().

I quote the documentation:

The strncpy() function is similar, except that not more than n bytes of src are copied. Thus, if there is no null byte among the first n bytes of src, the result will not be null-terminated.

Since there is no termination within the first 2 characters of the source, the destination is not terminated.

天气好吗我好吗 2024-11-22 12:48:15

使用 strcpy()strncpy() 的惯用方法:

如果您知道缓冲区有空间容纳字符串加上 NUL 终止符,则可以使用 strcpy( )。这可能会使用常量,或者在代码中进行检查(您应该确保检查是正确的)。

否则,您可以这样做:

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

这样做有以下缺点:

  • 它会截断字符串。
  • 它可能效率低下,因为它总是填充 length 字节。

还有 OpenBSD 的 strlcpy()

strcpy()/strncpy() 的任何其他使用都可能可疑,您应该仔细查看它们。

底线:避免使用 C 字符串函数来处理任何中等复杂的内容,尝试使用一些库来动态分配字符串。 Qmail/Postfix 自己推出,GNU 有 obstacks

Idiomatic ways to use strcpy() and strncpy():

If you know that the buffer has space for the string plus the NUL terminator, you can use strcpy(). This will probably use constants, or have checks in code (you should make sure the checks are right).

Otherwise, you can do:

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

which has the following disadvantages:

  • it can truncate strings.
  • it is potentially inefficient, since it always fills length bytes.

There is also OpenBSD's strlcpy().

Any other use of strcpy()/strncpy() is potentially suspicious, and you should look at them carefully.

Bottom line: avoid C string functions for anything moderately complex, try to use some library for dynamically allocated strings. Qmail/Postfix roll their own, GNU has obstacks.

灯下孤影 2024-11-22 12:48:15

你的字符串没有终止符,所以 valgrind 在它抱怨时可能是正确的。更改:

strncpy(test, "123", 2);

至:

strcpy(test, "12");

Your string has no terminator, so valgrind is probably right when it complains. Change:

strncpy(test, "123", 2);

to:

strcpy(test, "12");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文