C-条件跳转或移动取决于未初始化的值
当我尝试运行我的程序时,Valgrind出现以下错误:C-条件跳转或移动取决于未初始化的值,c,linked-list,valgrind,C,Linked List,Valgrind,当我尝试运行我的程序时,Valgrind出现以下错误: ==23152== Conditional jump or move depends on uninitialised value(s) ==23152== at 0x4C2D8D0: strcmp (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==23152== by 0x40096C: str_lower_cmp (functions.c:41) ==2
==23152== Conditional jump or move depends on uninitialised value(s)
==23152== at 0x4C2D8D0: strcmp (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23152== by 0x40096C: str_lower_cmp (functions.c:41)
==23152== by 0x400BB8: list_sort (list_sort.c:34)
==23152== by 0x400CC7: get_wdir_content (working_dir.c:27)
==23152== by 0x400C27: main (main.c:18)
==23152== Uninitialised value was created by a heap allocation
==23152== at 0x4C2C27B: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23152== by 0x400D4C: xmalloc (xfunctions.c:35)
==23152== by 0x400886: lower_string (functions.c:20)
==23152== by 0x400945: str_lower_cmp (functions.c:39)
==23152== by 0x400BB8: list_sort (list_sort.c:34)
==23152== by 0x400CC7: get_wdir_content (working_dir.c:27)
==23152== by 0x400C27: main (main.c:18)
==23152==
==23152== Conditional jump or move depends on uninitialised value(s)
==23152== at 0x400BBB: list_sort (list_sort.c:34)
==23152== by 0x400CC7: get_wdir_content (working_dir.c:27)
==23152== by 0x400C27: main (main.c:18)
==23152== Uninitialised value was created by a heap allocation
==23152== at 0x4C2C27B: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23152== by 0x400D4C: xmalloc (xfunctions.c:35)
==23152== by 0x400886: lower_string (functions.c:20)
==23152== by 0x400945: str_lower_cmp (functions.c:39)
==23152== by 0x400BB8: list_sort (list_sort.c:34)
==23152== by 0x400CC7: get_wdir_content (working_dir.c:27)
==23152== by 0x400C27: main (main.c:18)
==23152==
虽然我说不出有什么不对,但我猜它来自列表排序。c:
t_llist *list_sort(t_llist *list)
{
struct s_node *tmp;
tmp = list->head;
while (tmp != NULL)
{
if (tmp->next != NULL)
{
if (!tmp->name || !tmp->next->name)
printf("Reached.\n");
if (str_lower_cmp(tmp->name, tmp->next->name) > 0)
{
data_swap(tmp, tmp->next);
tmp = list->head;
}
else
tmp = tmp->next;
}
else
return (list);
}
return (list);
}
这是否意味着在某个时刻,tmp->name或tmp->next->name值未初始化
编辑(functions.c代码)
char*lower_字符串(char*s)
{
字符*res;
int i;
i=0;
res=xmalloc(sizeof(*res)*strlen+1);
而(s[i])
{
如果(s[i]>=“A”和&s[i]最初valgrind
告诉您正在运行strcmp
,内存地址分配为malloc
,来自函数lower\u string
,但没有分配初始值
这将意味着一种未定义的行为,这意味着,根据您的代码,它可能非常危险,因为它可能导致意外的结果
我建议在lower\u string
中使用calloc
编辑:您正在将s[i]
设置为0,而不是res[i]
(已分配并返回的指针)另一方面,我建议使用calloc
并检查res!=NULL
最初valgrind
告诉您正在运行strcmp
,内存地址分配为malloc
,来自函数下字符串,但没有分配初始值
这将意味着一种未定义的行为,这意味着,根据您的代码,它可能非常危险,因为它可能导致意外的结果
我建议在lower\u string
中使用calloc
编辑:您正在将s[i]
设置为0,而不是res[i]
(您已分配并返回的指针)。另一方面,我建议使用calloc
并检查res!=NULL
您的错误在下字符串中,您没有终止正在分配的字符串:
char *lower_string(char *s)
{
char *res;
int i;
i = 0;
res = xmalloc(sizeof(*res) * strlen(s) + 1);
while (s[i])
{
if (s[i] >= 'A' && s[i] <= 'Z')
res[i] = s[i] + 32;
else
res[i] = s[i];
i++;
}
s[i] = '\0'; // THIS IS WRONG
return (res);
}
请注意,如果将输入字符串作为const
参数正确传递,则会捕捉到这一点:
char *lower_string(const char *s) // MAKE PARAM CONST
这样做将无法编译,因为s[i]='\0'
赋值将违反常量条件。一般规则是,除非您需要修改作为by address参数传递的内容,否则将其设为常量您的错误在下字符串中您没有终止正在分配的字符串:
char *lower_string(char *s)
{
char *res;
int i;
i = 0;
res = xmalloc(sizeof(*res) * strlen(s) + 1);
while (s[i])
{
if (s[i] >= 'A' && s[i] <= 'Z')
res[i] = s[i] + 32;
else
res[i] = s[i];
i++;
}
s[i] = '\0'; // THIS IS WRONG
return (res);
}
请注意,如果将输入字符串作为const
参数正确传递,则会捕捉到这一点:
char *lower_string(const char *s) // MAKE PARAM CONST
这样做将无法编译,因为s[i]='\0'
赋值将违反常量条件。一般规则是,除非需要修改作为by address参数传递的内容,否则在“char*s”传递给lower_string的是一个空字符串,您的程序也会崩溃。按照jcm的说法调用calloc将有助于解决该问题,因为“char*s”传递给lower_string的是一个空字符串,您的程序也会崩溃。按照jcm的说法调用calloc将有助于解决该问题Hmmm,如果在使用列表指针之前检查它会发生什么情况?抱歉,哪个指针?t_llist*list?由于报告位于strcmp
中,您可以推断您正在为节点分配内存,这是pa使用valgrind调试分配器,然后通过调试strcmp检查所述指针值的模式。换句话说,是的,您可能通过值发送不确定的name
参数,或者从未正确填充和终止它所指向的实际数据。但不知道您实际如何构造你的列表,不可能说出你是如何犯这个错误的。是的,它甚至会告诉你在哪里错选了字符串,但没有填写:lower_string函数。c:20@DaanTimmer老实说,考虑到它根本不需要,最好不要这样做。嗯,如果在使用列表指针之前检查它会怎么样?对不起,哪个指针?不是_llist*列表?由于报告位于strcmp
中,您可以推断您正在为节点分配内存,这是valgrind调试分配器的模式FLING,然后通过其调试strcmp检查所述指针值的模式。换句话说,是的,您可能通过val发送不确定的名称
参数或者从不正确填充和终止它所指向的实际数据。如果不知道您实际上是如何构造列表的,就不可能说出您是如何犯错误的。是的,它甚至会告诉您在哪里对字符串进行了malloc'运算,但没有填充:lower_string函数。c:20@DaanTimmer老实说,最好不要这样做,考虑到它甚至不需要。@WhozCraig我同意。更新的响应;)。但是,为了澄清,我的意思是,使用strcmp
,它很可能会立即返回,您将进入else
块(我假设有if/else
检查strcmp
响应)我在xmalloc函数中调用malloc,在这里我检查它的返回。@Kernael然后,只需调用calloc
,而不是malloc
,您将得到所有分配的内存初始化0@Kernael这对修复您的警告消息有用吗?@WhozCraig我同意。更新的响应;)。但是,为了澄清,我的意思是,使用strcmp
,它很可能会立即返回,您将进入else
块(我假设有if/else
检查strcmp
响应)我在xmalloc函数中调用malloc,在这里我检查它的返回。@Kernael然后,只需调用calloc
,而不是malloc
,您将得到所有分配的内存初始化0@Kernael这对修复您的警告消息有用吗?谢谢,最后这是一个愚蠢的错误。也谢谢您的提示,我会使用它。@Kern如果你不能