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

时间:2018-02-04 15:32:15

标签: c dynamic-arrays coredump

我正在尝试创建一个接受用户输入并可以执行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 个答案:

答案 0 :(得分:0)

我认为有两个问题:

  1. 由于strdup中for循环中的条件,size不能保证被调用commands次,因此不是数组NULL的所有元素将被初始化。
  2. 我建议您在释放元素之前检查这些元素是否为for(int i = 0; i < size; i++){ if (command[i] != NULL) { printf("%d\n",i); free(commands[i]); } }

    pipe

    2。 由于getCommand函数中的for循环,numOfPipes被称为command次,并且可能每次为getCommand数组元素分配新内存,而不释放前一个分配内存。 我建议您在致电strdup(或RewriteRule ^user/([a-zA-Z0-9_-]+)/?$ user.php?u=$1 [L]

    之前检查并释放内存