我正在使用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==
谢谢
答案 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;