释放动态字符串数组时获取核心转储
Getting core dumps when freeing dynamic string array
我正在尝试创建一个接受用户输入并可以执行 Linux 和内置命令的 shell,到目前为止一切都很好。我的问题是我执行管道命令的功能有时会发生核心转储。当我遍历 char** 数组以释放每个索引时,我知道这是核心转储,但它只是时不时地进行核心转储。
这是我的函数,带有一些调试打印语句。
int getCommand(int index, char** commands, char **args, int size){
int i = 0;
for(i; i < size && args[index] != NULL && strcmp(args[index],"|"); i++{
commands[i] = strdup(args[index]);
index++;
}
if(i < size)
commands[i] = NULL;
if(index < size && args[index] != NULL && !strcmp(args[index],"|"))
index++;
return index;
}
void pipe(char **args, int size, int numOfPipes){
char **commands = malloc(size*sizeof(char**));
int index = 0;
int new_fd[2], old_fd[2], status;
pid_t pid;
for(int i = 0; i < (numOfPipes+1); i++){
index = getCommand(index, commands, args, size);
if(pipe(new_fd[2] == -1){
printf("Pipe failed\n");
exit(1);
}
else if((pid = fork()) < 0){
printf("Fork failed\n");
exit(1);
}
else if(pid == 0){
if(i > 0){
dup2(old_fd[0],0);
close(old_fd[1]);
}
if(i < numOfPipes){
dup2(new_fd[1],1);
close(new_fd[0]);
}
if(execvp(*commands,commands) < 0){
printf("Command could not be executed.");
exit(1);
}
}
else{
close(old_fd[0]);
close(old_fd[1]);
wait(&status);
old_fd[0] = new_fd[0];
old_fd[1] = new_fd[1];
}
printf("Free strings\n");
/* Here is where it core dumps */
for(int i = 0; i < size; i++){
printf("%d\n",i);
free(commands[i]);
}
printf("Freeing pointer\n");
free(commands);
}
谁能帮我看看我哪里出错了?
我认为有两个问题:
- 由于
getCommand
中 for 循环的条件,strdup
不能保证被调用 size
次,因此并不是数组的所有元素 commands
将被初始化。
我建议您在释放元素之前检查它们是否 NULL
:
for(int i = 0; i < size; i++){
if (command[i] != NULL) {
printf("%d\n",i);
free(commands[i]);
}
}
2。
由于 pipe
函数中的 for 循环,getCommand
被调用 numOfPipes
次并且可能每次都为 command
数组元素分配新内存,而不释放前一个分配的内存。
我建议你在调用getCommand
(或strdup
)
之前检查并释放内存
我正在尝试创建一个接受用户输入并可以执行 Linux 和内置命令的 shell,到目前为止一切都很好。我的问题是我执行管道命令的功能有时会发生核心转储。当我遍历 char** 数组以释放每个索引时,我知道这是核心转储,但它只是时不时地进行核心转储。
这是我的函数,带有一些调试打印语句。
int getCommand(int index, char** commands, char **args, int size){
int i = 0;
for(i; i < size && args[index] != NULL && strcmp(args[index],"|"); i++{
commands[i] = strdup(args[index]);
index++;
}
if(i < size)
commands[i] = NULL;
if(index < size && args[index] != NULL && !strcmp(args[index],"|"))
index++;
return index;
}
void pipe(char **args, int size, int numOfPipes){
char **commands = malloc(size*sizeof(char**));
int index = 0;
int new_fd[2], old_fd[2], status;
pid_t pid;
for(int i = 0; i < (numOfPipes+1); i++){
index = getCommand(index, commands, args, size);
if(pipe(new_fd[2] == -1){
printf("Pipe failed\n");
exit(1);
}
else if((pid = fork()) < 0){
printf("Fork failed\n");
exit(1);
}
else if(pid == 0){
if(i > 0){
dup2(old_fd[0],0);
close(old_fd[1]);
}
if(i < numOfPipes){
dup2(new_fd[1],1);
close(new_fd[0]);
}
if(execvp(*commands,commands) < 0){
printf("Command could not be executed.");
exit(1);
}
}
else{
close(old_fd[0]);
close(old_fd[1]);
wait(&status);
old_fd[0] = new_fd[0];
old_fd[1] = new_fd[1];
}
printf("Free strings\n");
/* Here is where it core dumps */
for(int i = 0; i < size; i++){
printf("%d\n",i);
free(commands[i]);
}
printf("Freeing pointer\n");
free(commands);
}
谁能帮我看看我哪里出错了?
我认为有两个问题:
- 由于
getCommand
中 for 循环的条件,strdup
不能保证被调用size
次,因此并不是数组的所有元素commands
将被初始化。
我建议您在释放元素之前检查它们是否 NULL
:
for(int i = 0; i < size; i++){
if (command[i] != NULL) {
printf("%d\n",i);
free(commands[i]);
}
}
2。
由于 pipe
函数中的 for 循环,getCommand
被调用 numOfPipes
次并且可能每次都为 command
数组元素分配新内存,而不释放前一个分配的内存。
我建议你在调用getCommand
(或strdup
)