简体   繁体   中英

I have a 'Segmentation Problem' while printing parsed parts of a String

I am writing a simple Shell for school assignment and stuck with a segmentation problem. Initially, my shell parses the user input to remove whitespaces and endofline character, and seperate the words inside the input line to store them in a char **args array. I can seperate the words and can print them without any problem, but when storing the words into a char **args array, and if argument number is greater than 1 and is odd, I get a segmentation error.

I know the problem is absurd, but I stuck with it. Please help me.

This is my parser code and the problem occurs in it:截屏

char **parseInput(char *input){
int idx = 0;
char **parsed = NULL;
int parsed_idx = 0;

while(input[idx]){
    if(input[idx] == '\n'){
        break;

    }
    else if(input[idx] == ' '){
        idx++;

    }
    else{
        char *word = (char*) malloc(sizeof(char*));
        int widx = 0; // Word index
        word[widx] = input[idx];
        idx++;
        widx++;
        while(input[idx] && input[idx] != '\n' && input[idx] != ' '){
            word = (char*)realloc(word, (widx+1)*sizeof(char*));
            word[widx] = input[idx];
            idx++;
            widx++;
        }

        word = (char*)realloc(word, (widx+1)*sizeof(char*));
        word[widx] = '\0';
        printf("Word[%d] --> %s\n", parsed_idx, word);

        if(parsed == NULL){
            parsed = (char**) malloc(sizeof(char**));
            parsed[parsed_idx] = word;
            parsed_idx++;
        }else{
            parsed = (char**) realloc(parsed, (parsed_idx+1)*sizeof(char**));
            parsed[parsed_idx] = word;
            parsed_idx++;
        }

    }
}
int i = 0;

while(parsed[i] != NULL){
    printf("Parsed[%d] --> %s\n", i, parsed[i]);
    i++;
}

return parsed;

}

In your code you have the loop

while(parsed[i] != NULL) { ... }

The problem is that the code never sets any elements of parsed to be a NULL pointer.

That means the loop will go out of bounds, and you will have undefined behavior .

You need to explicitly set the last element of parsed to be a NULL pointer after you parsed the input:

while(input[idx]){
    // ...
}

parsed[parsed_idx] = NULL;

On another couple of notes:

  • Don't assign back to the same pointer you pass to realloc . If realloc fails it will return a NULL pointer, but not free the old memory. If you assign back to the pointer you will loose it and have a memory leak. You also need to be able to handle this case where realloc fails.

  • A loop like

    int i = 0; while (parsed[i].= NULL) { //..; i++; }

    is almost exactly the same as

    for (int i = 0; parsed[i];= NULL. i++) { //... }

    Please use a for loop instead, it's usually easier to read and follow. Also for a for loop the "index" variable ( i in your code) will be in a separate scope, and not available outside of the loop. Tighter scope for variables leads to less possible problems.

  • In C you shouldn't really cast the result of malloc (or realloc ) (or really any function returning void * ). If you forget to #include <stdlib.h> it could lead to hard to diagnose problems.

Also, a beginner might find the -pedantic switch helpful on your call to the compiler. That switch would have pointed up most of the other suggestions made here. I personally am also a fan of -Wall, though many find it annoying instead of helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM