valgrind неверное чтение размера 1 на execvp

Я использую execvp для проекта мини-оболочки, а valgrind показывает огромную утечку памяти в одной строке: строка 263.

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

Кто-то видит, откуда проблема?

173 char **token_tab(char *line)
174 {
175   char **res_tab = NULL;
176   token *tok_tab = NULL;
177   token *tmp = NULL;
178   int cpt = 0;
179 
180   tok_tab = generate_token(line);
181   tmp = tok_tab;
182 
183   while (tmp != NULL)
184   {
185     cpt++;
186     tmp = tmp->next;
187   }
188 
189   res_tab = malloc(sizeof (char *) * cpt);
190 
191   tmp = tok_tab;
192 
193   for (int i = 0; i < cpt; ++i)
194   {
195     res_tab[i] = malloc(sizeof (char) * my_strlen(tmp->word));
196     my_strcpy(res_tab[i], tmp->word);
197     tmp = tmp->next;
198   }
199   res_tab[cpt - 1] = NULL;
200 
201   return res_tab;
202 }


     int exec_cmd(char **tab_word, pid_t pid)
259 {
260   int status = -5;
261   pid = fork();
262   if (pid == 0)
263     execvp(tab_word[0], tab_word);
264   else
265     wait(&status);
266 
267   free_double_char(tab_word);
268 
269   return WEXITSTATUS(status);
270 }

    minishell$ls
==22475== Conditional jump or move depends on uninitialised value(s)
==22475==    at 0x400E91: main (minishell.c:357)
==22475== 
==22475== Conditional jump or move depends on uninitialised value(s)
==22475==    at 0x400E69: main (minishell.c:358)
==22475== 
==22475== Conditional jump or move depends on uninitialised value(s)
==22475==    at 0x401177: generate_token (new_lex.c:38)
==22475==    by 0x400AA4: token_tab (minishell.c:180)
==22475==    by 0x400EA7: main (minishell.c:361)
==22475== 
==22475== Invalid write of size 1
==22475==    at 0x402B6B: my_strcpy (my_strcpy.c:10)
==22475==    by 0x400B47: token_tab (minishell.c:196)
==22475==    by 0x400EA7: main (minishell.c:361)
==22475==  Address 0x51feb22 is 0 bytes after a block of size 2 alloc'd
==22475==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22475==    by 0x400B1B: token_tab (minishell.c:195)
==22475==    by 0x400EA7: main (minishell.c:361)
==22475== 
==22476== Invalid read of size 1
==22476==    at 0x4C2DBB0: __GI_strchr (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22476==    by 0x4EF8978: execvpe (execvpe.c:60)
==22476==    by 0x400CB1: exec_cmd (minishell.c:263)
==22476==    by 0x400EDE: main (minishell.c:366)
==22476==  Address 0x51feb22 is 0 bytes after a block of size 2 alloc'd
==22476==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22476==    by 0x400B1B: token_tab (minishell.c:195)
==22476==    by 0x400EA7: main (minishell.c:361)
==22476== 
==22476== Invalid read of size 1
==22476==    at 0x4C2E0F4: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22476==    by 0x4EF8AC4: execvpe (execvpe.c:101)
==22476==    by 0x400CB1: exec_cmd (minishell.c:263)
==22476==    by 0x400EDE: main (minishell.c:366)
==22476==  Address 0x51feb22 is 0 bytes after a block of size 2 alloc'd
==22476==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22476==    by 0x400B1B: token_tab (minishell.c:195)
==22476==    by 0x400EA7: main (minishell.c:361)
==22476== 
==22476== Invalid read of size 1
==22476==    at 0x4C2FF3E: __GI_memcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22476==    by 0x4EF8B1D: execvpe (execvpe.c:126)
==22476==    by 0x400CB1: exec_cmd (minishell.c:263)
==22476==    by 0x400EDE: main (minishell.c:366)
==22476==  Address 0x51feb22 is 0 bytes after a block of size 2 alloc'd
==22476==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22476==    by 0x400B1B: token_tab (minishell.c:195)
==22476==    by 0x400EA7: main (minishell.c:361)
==22476== 
==22476== Syscall param execve(argv[i]) points to unaddressable byte(s)
==22476==    at 0x4EF8337: execve (execve.c:33)
==22476==    by 0x4EF8B88: execvpe (execvpe.c:149)
==22476==    by 0x400CB1: exec_cmd (minishell.c:263)
==22476==    by 0x400EDE: main (minishell.c:366)
==22476==  Address 0x51feb22 is 0 bytes after a block of size 2 alloc'd
==22476==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22476==    by 0x400B1B: token_tab (minishell.c:195)
==22476==    by 0x400EA7: main (minishell.c:361)
==22476== 

благодарю вас

2 ответа

В вашем коде вы не выделяете для последнего '\0' символ для строк.

Линия

res_tab[i] = malloc(sizeof (char) * my_strlen(tmp->word));

следует выделить еще 1 символ

res_tab[i] = malloc(sizeof (char) * (my_strlen(tmp->word) + 1) );

Я предполагаю, что здесь my_strlen() похож на strlen() и не считается '\0' в длину.

У вас утечка памяти. Вы перезаписываете последний malloc в res_tab[cpt-1] с NULL без освобождения в первую очередь. Если последний токен не должен быть пропущен:

res_tab = malloc(sizeof (char *) * (cpt+1));

а также

res_tab[cpt] = NULL;
Другие вопросы по тегам