C-条件跳转或移动取决于未初始化的值

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

当我尝试运行我的程序时,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)
==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如果你不能