首页 > 解决方案 > 我找不到分段错误的原因

问题描述

我正在尝试在 C for Linux 中创建一个基本的类似 shell 的程序,但我遇到了一些问题。我在创建的函数的某处遇到分段错误parse_cmdline,但我希望 argumens = parse_cmdline (cmdline); 可能不是实现我想要做的事情的最佳方式。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

char** parse_cmdline(const char *cmdline){

    char** input;
    int counter = 0;
    char* token;
    token = strtok(cmdline);
    
    int tokenlen = strlen(token);
    
    input = realloc(input , sizeof(char*)+tokenlen*sizeof(char));
    input[counter] = token;
        
    while( token != NULL ) {
            token = strtok(NULL, " ");
            printf("%s\n",token);
            tokenlen = strlen(token);
            input = realloc(input , sizeof(char*)+tokenlen*sizeof(char));
            counter++;
            input[counter] = token;
    }
    return input;
}

int main(){

    char* cmdline = NULL;
    size_t cmdlength = 0 ;
    char** arguments;

    int status;
    pid_t pid;
    while (1){
    
        getline(&cmdline , &cmdlength , stdin);
        arguments = parse_cmdline(cmdline);

        pid = fork();
        if(pid == 0){
        
            if(access(arguments[0], F_OK) == 0 ) {
            
                    if(access(arguments[0], X_OK)){
                    
                        execv(arguments[0],arguments);
                        exit(0);
                        
                    } else {
                    
                        printf("%s: Permission denied",arguments[0]);
                        exit(-1);
                    
                    }
                    
            } else {
            
                printf("%s: No such file or directory",arguments[0]);
                exit(-1);
            
            }
            
        } else {
        
            waitpid(-1, &status, 0);
            
        }
            
        free(arguments);
        cmdline = NULL ;
        cmdlength = 0 ;
    }   
    return 0;
}

标签: csegmentation-fault

解决方案


有两个问题立即跳出来给我:

  1. 正如@Bob__ 在评论中观察到的那样,strtok()具有破坏性,因此您不应将 aconst char *作为其第一个参数。您的编译器至少应该对此发出警告。不要忽略编译器的警告,尤其是在寻找错误时。如果您对该字符串的修改parse_cmdline()没有意见,请从其参数中删除const(并且不要将const数据传递给函数)。如果您不想修改输入数据,请制作本地非const副本或使用strtok().

  2. strtok()NULL当没有更多令牌时返回,但您在没有首先测试的情况下使用它的结果。对于初始调用和循环中的调用,条件中的空值检查while来得太晚了。strtok()


推荐阅读