valgrind在execvp上读取大小为1的无效内容

时间:2015-07-14 07:28:54

标签: c memory-leaks valgrind execvp

我正在使用execvp进行一个迷你shell项目,而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 :(得分: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'

答案 1 :(得分:0)

你有内存泄漏。使用NULL将最后一个malloc覆盖到res_tab [cpt-1]而不先释放。如果不应该跳过最后一个令牌:

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

res_tab[cpt] = NULL;