退出功能后的分段故障

时间:2017-09-12 07:06:02

标签: c shell parsing segmentation-fault

解析线函数处理程序:

char **parse_line(char *input) {
    char **tokens;
    char *token;
    char *seps = " \n";

    token = strtok(input, seps);
    int i = 0;
    while (token != NULL) {
        tokens[i] = token;
        i++;

        token = strtok(NULL, seps);
    }

    tokens[i] = NULL;

    return tokens;
}

管道函数处理程序:

void pipes(char *input) {
    const char ch = '|';
    printf("%s", input);

    char *c;

    if (strchr(input, ch) == NULL) {
        printf("no | found\n");
        return;
    }

    printf("%s\n", input);

    char *p = strtok(input, "|");

    int i = 0;
    char *array0;
    char *array1;

    while (p != NULL) {
        if (i == 0)
            array0 = p;
        else
            array1 = p;
        i++;
        printf("p: %s\n", p);

        p = strtok( NULL, "|" );
    }

    printf("opening\n");

    parse_line(array1);
}

主要

int main(int argc, const char *argv[]) {
    while (1) {
        printf("> ");
        //read line
        char input[100];
        fgets(input, sizeof(input), stdin);

        pipes(input);
    }
    ...

gdb输出:

(gdb) cat scores | grep villanova
Undefined catch command: "scores | grep villanova".  Try "help catch".
(gdb) run
Starting program: ******* 
> cat scores | grep villanova
cat scores | grep villanova
cat scores | grep villanova

while
while
opening
 grep villanova


Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffddf2 in ?? ()
(gdb) x/s 0x00007fffffffddf2
0x7fffffffddf2: "villanova"
(gdb) p $_siginfo._sifields._sigfault.si_addr
$1 = (void *) 0x7fffffffddf2
(gdb) q

当使用gdb单步执行时,它会在到达pipes函数的末尾后发生故障。任何人都知道为什么/我如何找出原因并解决它。

我正试图在调试方面做得更好,但这让我很难过,我很感激我能得到的任何帮助:)

1 个答案:

答案 0 :(得分:3)

函数parse_line没有为tokens分配一个数组来指向。代码有不确定的行为。

这是一个简单的更正版本:

char **parse_line(char *input) {
    size_t i = 0;
    char **tokens = malloc(sizeof(*tokens));
    char *token;
    const char *seps = " \n";
    if (tokens == NULL)
        return NULL;

    token = strtok(input, seps);
    while (token != NULL) {
        char **newp = realloc(tokens, (i + 2) * sizeof(*newp));
        if (newp == NULL) {
            free(tokens);
            return NULL;
        }
        tokens = newp;
        tokens[i++] = token;
        token = strtok(NULL, seps);
    }
    tokens[i] = NULL;

    return tokens;
}