释放动态字符串数组时获取核心转储

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);
}

谁能帮我看看我哪里出错了?

我认为有两个问题:

  1. 由于 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

之前检查并释放内存