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

execvp上大小为1的valgrind读取无效,c,memory-leaks,valgrind,execvp,C,Memory Leaks,Valgrind,Execvp,我在一个迷你shell项目中使用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;

我在一个迷你shell项目中使用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== 
173字符**标记选项卡(字符*行)
174 {
175字符**res_tab=NULL;
176令牌*tok_tab=NULL;
177令牌*tmp=NULL;
178 int cpt=0;
179
180 tok_tab=生成_令牌(行);
181 tmp=tok_标签;
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_标签;
192
193表示(int i=0;iword));
196我的简历(简历表[i],tmp->word);
197 tmp=tmp->next;
198   }
199 res_tab[cpt-1]=NULL;
200
201返回res_选项卡;
202 }
int exec\u cmd(字符**制表符\u字,pid\u t pid)
259 {
260整数状态=-5;
261 pid=fork();
262如果(pid==0)
263 execvp(tab_-word[0],tab_-word);
264其他
265等待(和状态);
266
267个自由双字符(制表符);
268
269返回WEXIT状态(状态);
270 }
迷你地狱
==22475==条件跳转或移动取决于未初始化的值
==22475==at 0x400E91:main(minishell.c:357)
==22475== 
==22475==条件跳转或移动取决于未初始化的值
==22475==0x400E69:main(minishell.c:358)
==22475== 
==22475==条件跳转或移动取决于未初始化的值
==22475==at 0x401177:生成令牌(新的\u lex.c:38)
==22475==0x400AA4:token_选项卡(minishell.c:180)
==22475==0x400EA7:main(minishell.c:361)
==22475== 
==22475==大小为1的无效写入
==22475==0x402B6B:my_strcpy(my_strcpy.c:10)
==22475==0x400B47:token_选项卡(minishell.c:196)
==22475==0x400EA7:main(minishell.c:361)
==22475==地址0x51feb22是大小为2的块分配后的0字节
==22475==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==22475==0x400B1B:token_选项卡(minishell.c:195)
==22475==0x400EA7:main(minishell.c:361)
==22475== 
==22476==大小为1的读取无效
==22476==0x4C2DB0:u_GI_strchr(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==22476==by 0x4EF8978:execvpe(execvpe.c:60)
==22476==0x400CB1:exec_cmd(minishell.c:263)
==22476==0x400EDE:main(minishhell.c:366)
==22476==地址0x51feb22是大小为2的块分配后的0字节
==22476==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==22476==0x400B1B:token_选项卡(minishell.c:195)
==22476==0x400EA7:main(minishell.c:361)
==22476== 
==22476==大小为1的读取无效
==22476==at 0x4C2E0F4:strlen(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==22476==0x4EF8AC4:execvpe(execvpe.c:101)
==22476==0x400CB1:exec_cmd(minishell.c:263)
==22476==0x400EDE:main(minishhell.c:366)
==22476==地址0x51feb22是大小为2的块分配后的0字节
==22476==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==22476==0x400B1B:token_选项卡(minishell.c:195)
==22476==0x400EA7:main(minishell.c:361)
==22476== 
==22476==大小为1的读取无效
==22476==0x4C2FF3E:u GI_memcpy(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==22476==0x4EF8B1D:execvpe(execvpe.c:126)
==22476==0x400CB1:exec_cmd(minishell.c:263)
==22476==0x400EDE:main(minishhell.c:366)
==22476==地址0x51feb22是大小为2的块分配后的0字节
==22476==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==22476==0x400B1B:token_选项卡(minishell.c:195)
==22476==0x400EA7:main(minishell.c:361)
==22476== 
==22476==Syscall param execve(argv[i])指向不可寻址字节
==22476==at 0x4EF8337:execve(execve.c:33)
==22476==0x4EF8B88:execvpe(execvpe.c:149)
==22476==0x400CB1:exec_cmd(minishell.c:263)
==22476==0x400EDE:main(minishhell.c:366)
==22476==地址0x51feb22是大小为2的块分配后的0字节
==22476==at 0x4C2AB80:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==22476==0x400B1B:token_选项卡(minishell.c:195)
==22476==0x400EA7:main(minishell.c:361)
==22476== 

谢谢

在您的代码中,您没有为字符串分配最后一个
'\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'

您有内存泄漏。使用NULL覆盖最后一个malloc to res_选项卡[cpt-1],而不首先释放。如果不应跳过最后一个令牌:

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


只是问,你为什么不为valgrind报告的其他错误而烦恼?顺便说一句,更轻松的是,这是
泄漏
,而不是
韭菜
。我只是一个接一个地治疗他们。我现在是代码的大和平。。。我试图让它更干净,事实上,这段代码并不是一直都有效,如果我发出两次echo命令,它就会开始打印坏字符……”“无效读取”!=“内存泄漏”。我猜数组
tab\u word
没有正确初始化。变量“tmp”是如何定义的?我试图用(my\u strlen(tmp->word)+1)来malloc res\u tab,然后res\u tab[I][my\u strlen(tmp->word)]='\0',但它不起作用…@threejay复制'\0'的应该是您的my\u strpy
res_tab[cpt] = NULL;