gpt4 book ai didi

c - Valgrind-snprintf : Conditional jump or move depends on uninitialised value(s)

转载 作者:太空宇宙 更新时间:2023-11-04 06:59:25 24 4
gpt4 key购买 nike

通过 valgrind 启动程序后,我收到以下消息:

==9290== Conditional jump or move depends on uninitialised value(s)
==9290== at 0x4E82A03: vfprintf (vfprintf.c:1661)
==9290== by 0x4EA9578: vsnprintf (vsnprintf.c:119)
==9290== by 0x4E8B531: snprintf (snprintf.c:33)
==9290== by 0x400820: _function (in /home/snp/prog/TEST)
==9290== by 0x4006D5: start (in /home/snp/prog/TEST)
==9290== by 0x40085C: main (in /home/snp/prog/TEST)
==9290== Uninitialised value was created by a heap allocation
==9290== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9290== by 0x400715: init (in /home/snp/prog/TEST)
==9290== by 0x400857: main (in /home/snp/prog/TEST)

以下代码重现错误:

#include <net/if.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>

#define TARGET "8.8.8.8"
#define DEVICE "eth0"

static int _function(void);

struct remote
{
char *target;
char device[IFNAMSIZ];
};

struct remote * st_args;

int start(void)
{
return (_function());
}

int init(void)
{
st_args = malloc (sizeof (struct remote));
if (st_args == NULL)
return (-1);

st_args->target = malloc (sizeof (TARGET)+1);
if (st_args->target == NULL)
{
free (st_args);
return (-1);
}

strncpy(st_args->target, TARGET , sizeof(TARGET)-1);
strncpy(st_args->device, DEVICE, IFNAMSIZ-1);

return 0;
}

void stop(void)
{
if (st_args != NULL)
{
free (st_args->target);
free (st_args);
}
}

static int _function(void)
{
char cmd[256];

memset(cmd, 0, sizeof(cmd));

snprintf(cmd, sizeof(cmd), "ping -I %s %s", st_args->device, st_args->target);

return 0;
}

int main(int argc, char **argv)
{
init();
start();
stop();
return 0;
}

我仍然不明白这个问题,为什么 valgrind 不接受 snprintf 命令。此外,该数组包含行执行后的预期字符串。

最佳答案

Valgrind 的消息,

==9290== Conditional jump or move depends on uninitialised value(s)

是不言自明的:程序被观察到依赖于未初始化的内存来做出决定。在标准库函数中发生这种情况,很自然地假设函数参数有问题。由于您专门打印字符串,最可能的原因是其中一个字符串参数未终止。

事实上,至少有一个是。考虑这段代码:

#define TARGET "8.8.8.8"

[...]

strncpy(st_args->target, TARGET , sizeof(TARGET)-1);

为了安全起见,你搬起石头砸了自己的脚。 strncpy()最多复制指定的字节数,但它不会在之后附加终止符。因此,其 Linux 手册页包含此警告:

Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null terminated.

您已确保该警告中描述的情况发生了 -- 没有写入空终止符,并且为 st_args->target 分配了最后一个字节。保持未初始化状态。

由于您小心地为整个字符串分配了足够的空间,包括终止符,strncpy()无论如何都是矫枉过正。只需使用 strcpy() .或者实际上,如果您的系统有 strdup()或者你愿意写一个实现,然后 strdup()malloc()干净多了+ strcpy() .

或者,如果您想使用 strncpy()那么通过跟进每个 strncpy() 来确保目标字符串终止是个好主意。通过手动将终止符写入目标的最后一个字节来调用。在这种情况下,这将是

st_args->target[sizeof(TARGET)] = '\0';

另请注意,实际上您为 sizeof 分配的字节比您需要的多了一个字节。字符串文字包括终止符。上面的代码是为实际的一字节过多分配编写的。

关于c - Valgrind-snprintf : Conditional jump or move depends on uninitialised value(s),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40423114/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com