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

时间:2013-11-20 14:23:40

标签: 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)
==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==

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

编辑(functions.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] = '\0';
  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);
}

3 个答案:

答案 0 :(得分:3)

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

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

我建议在calloc中使用lower_string

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

答案 1 :(得分:1)

您的错误出现在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] = '\0'; // THIS IS WRONG
    return (res);
}

标记的行应为:

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

请注意,如果您将输入字符串正确地作为const参数传递,则会捕获此信息:

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

这样做将无法编译,因为您的s[i] = '\0'赋值会违反const条件。一般规则,除非您需要修改作为by-address参数传递的内容,否则将其设为const

答案 2 :(得分:0)

当传递给lower_string的“char * s”是一个空字符串时,你也有一个崩溃的程序。将calloc称为jcm表示将有助于解决该问题