«Условный переход или перемещение зависит от неинициализированных значений» при освобождении символа ** - PullRequest
2 голосов
/ 07 октября 2019

Я пишу минималистскую оболочку на С для школы. Это работает нормально, но с помощью 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==

В начале я делаю копию переменных окружения (extern char **environ) в main():

 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);
  }

У меня также возникает проблема, когда другие части программы используют копию. Любая помощь будет оценена.

Ответы [ 2 ]

3 голосов
/ 07 октября 2019

Здесь вы выделяете некоторую неинициализированную память для копирования.

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

Затем вы делаете указатель, указывающий на него.

cpy_ptr = copy;

Пока все хорошо, но затем вы делаете это:

while (*cpy_ptr)

copy, и, следовательно, cpy_ptr указывает на неинициализированную память. Вам нужно инициализировать его перед разыменованием указателя.

Я бы также отметил, что вы используете sizeof(copy) вместо sizeof(*copy). Конечно, в этом случае он дает тот же результат, но это только потому, что это двойной указатель.

2 голосов
/ 07 октября 2019

Проблема в том, что ваше выражение:

while (*cpy_ptr)

проверяет неправильное, неинициализированное пространство. Вы, вероятно, хотите протестировать оригинал:

while (*env_ptr)

Т.е. пока мы не достигли конца исходного вектора строк с нулевым символом в конце ...

Кроме того, ваша последняя строкаdubious:

cpy_ptr = NULL;

Это не имеет никакого эффекта, потому что вы присваиваете локальную переменную, которая не имеет следующего использования перед выходом из области видимости. Вы почти наверняка хотели это:

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