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



当我试图运行我的程序时,我从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==

虽然我不能说出了什么问题,但我猜它来自listrongort.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值未初始化?

EDIT(函数.c代码)

    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] = '';
  return (res);
}
int             str_lower_cmp(char *s1, char *s2)
{
  char          *tmp1;
  char          *tmp2;
  int           res;
  tmp1 = lower_string(s1);
  tmp2 = lower_string(s2);
  res = strcmp(tmp1, tmp2);
  free(tmp1);
  free(tmp2);
  return (res);
}

最初,valgrind告诉您正在运行strcmp,其内存地址由malloc分配,来自函数lower_string,但没有分配初始值。

这意味着一种未定义的行为,这意味着,根据您的代码,这可能是非常危险的,因为可能会导致意外的结果。

我建议在lower_string中使用calloc

编辑:您将s[i]设置为0,而不是res[i](您已分配并返回的指针)。另一方面,我建议使用calloc并检查res!=NULL

您的错误在lower_string中。您没有终止正在分配的字符串:

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] = ''; // THIS IS WRONG
    return (res);
}

标记线应为:

    res[i] = ''; // THIS IS RIGHT

注意,如果您正确地将输入字符串作为const参数进行传递,就会发现这种情况:

char *lower_string(const char *s) // MAKE PARAM CONST

这样做会导致编译失败,因为s[i] = ''赋值违反了const条件。一般规则,除非需要修改作为按地址参数传递的内容,否则将其设为const

当传递给lower_string的"char*s"是空字符串时,程序也会崩溃。正如jcm所说,调用calloc将有助于解决

问题

相关内容

  • 没有找到相关文章

最新更新