"Conditional jump or move depends on uninitialised values" 同时释放一个字符 **

"Conditional jump or move depends on uninitialised values" while freeing a char **

我正在用 C 为学校写一个极简主义 shell。它工作正常,但是使用 Valgrind 我遇到了这个错误,我不知道我做错了什么。我在程序开始时得到它:

==9396== Conditional jump or move depends on uninitialised value(s)
==9396==    at 0x1093AC: get_env (msh.c:59)
==9396==    by 0x1094FA: main (msh.c:106)
==9396==  Uninitialised value was created by a heap allocation
==9396==    at 0x483577F: malloc (vg_replace_malloc.c:309)
==9396==    by 0x109341: get_env (msh.c:55)
==9396==    by 0x1094FA: main (msh.c:106)
==9396==

一开始,我在main():

中复制了一份环境变量(extern char **environ)
 if (!(env = get_env(environ)))
         return (1);

函数如下:

 char    **get_env(char **environ)
 {
          char    **copy;
          char    **env_ptr;
          char    **cpy_ptr;

          if (!(copy = malloc(sizeof(copy) * get_tab_size(environ) + 1)))
                  exit(EXIT_FAILURE);
          env_ptr = environ;
          cpy_ptr = copy;
          while (*cpy_ptr)
          {
                  if (!(*cpy_ptr = ft_strdup(*env_ptr)))
                          exit(EXIT_FAILURE);
                  cpy_ptr++;
                  env_ptr++;
          }
          cpy_ptr = NULL;
          return (copy);
  }

在程序结束时,我用这个函数释放副本并得到同样的错误:

==9396== Conditional jump or move depends on uninitialised value(s)
==9396==    at 0x10BFC0: ft_free_tab2 (in /home/pom/dev/19/msh/msh)
==9396==    by 0x109593: main (msh.c:126)
==9396==  Uninitialised value was created by a heap allocation
==9396==    at 0x483577F: malloc (vg_replace_malloc.c:309)
==9396==    by 0x109341: get_env (msh.c:55)
==9396==    by 0x1094FA: main (msh.c:106)

释放函数如下:

  void    ft_free_tab2(char **env)
  {
          char    **ptr;

          if (!env)
                  return ;
          ptr = env;
          while (*ptr)
          {
                  free(*ptr);
                  ptr++;
          }
          free(env);
  }

当程序的其他部分使用副本时,我也遇到了问题。任何帮助将不胜感激。

问题是你的表达方式:

while (*cpy_ptr)

正在测试未初始化的 malloced space。您可能想要测试原始版本:

while (*env_ptr)

即虽然我们还没有到达原始的以 null 结尾的字符串向量的末尾...

此外,你的最后一行是可疑的:

cpy_ptr = NULL;

这没有任何效果,因为您正在分配给一个在超出范围之前没有下一次使用的局部变量。你几乎肯定想要这个:

*cpy_ptr = NULL;  // Null-terminate the copied vector

这里分配一些未初始化的内存用于拷贝。

copy = malloc(sizeof(copy) * get_tab_size(environ) + 1)

然后你做一个指针指向它。

cpy_ptr = copy;

到目前为止还不错,但是你这样做了:

while (*cpy_ptr)

copy,因此 cpy_ptr 也指向未初始化的内存。您需要在取消引用指针之前对其进行初始化。

我还要指出,您使用 sizeof(copy) 而不是 sizeof(*copy)。当然,在这种情况下它给出了相同的结果,但这只是因为它是一个双指针。