cppDreamer
cppDreamer

Reputation: 11

C char* array allocation

I was writing a function to parse command line as char* arguments array to another program but then I faced a problem allocating and/or reading the resulting buffer. I am stuck on that for about 2 days and 1000+ google searches later and I just can't figure it out all by myself.

#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h> //for malloc, realloc 

char** parse_cmdline(const char* cmdline) {
    int wrdc = 0; //word count
    int wrd_len = 0; //current word length
    char** args = NULL; //result buffer, filled with arguments
    int i; //counter of characters read from cmdline 
    for(i = 0; ; ++i){  
        if(cmdline[i] == '\n') {
            if(wrd_len > 0) {
                ++wrdc;
                args = realloc(args, wrdc * sizeof(char*));
                memcpy((void*)&args[wrdc - 1], (void*) &cmdline[i - wrd_len], wrd_len);
                printf("EOL found\n");
                wrd_len = 0;
            }
            break;
        } 
        else if(cmdline[i] == ' ') {
            if(wrd_len > 0) {
                ++wrdc;
                args = realloc(args, wrdc * sizeof(char*));
                memcpy((void*)&args[wrdc - 1], (void*) &cmdline[i - wrd_len], wrd_len);
                printf("space found!\n");
                wrd_len = 0;    
            }
        }
        else if(cmdline[i] > 32 && cmdline[i] < 127) {
            ++wrd_len;
            printf("char found !\n");
        }
        //FOR DEBUGGING
        printf("i = %d, wrdc = %d, wrd_len = %d\n", i, wrdc, wrd_len);
    }
    printf("%d words in command\n", wrdc);
    return args;
}

int main(int argc, char* argv[]) {
    char buffer[200];
    while(read(STDIN_FILENO, buffer, 200) > 0) {
        char** data = parse_cmdline(buffer);
        printf("%s\n", data[0]);
        memset(buffer, 0, 200);
        free(data);
    }
    return 0;
}

Upvotes: 0

Views: 82

Answers (1)

timrau
timrau

Reputation: 23058

   else if(cmdline[i] == ' ') {
        if(wrd_len > 0) {
            ++wrdc;
            args = realloc(args, wrdc * sizeof(char*));
            memcpy((void*)&args[wrdc - 1], (void*) &cmdline[i - wrd_len], wrd_len);
            printf("space found!\n");
            wrd_len = 0;    
        }
    }

Here the pointer stored in args[wrdc-1] is uninitialized and pointed to somewhere unknown. You shouldn't just memcpy() the cmdline into args[wrdc-1].

Allocate the memory for one single argument before memcpy():

args[wrdc-1] = calloc(wrd_len+1, sizeof(char));

Note the +1 and calloc() for terminating NULL character. Remember to free them in main().

Upvotes: 1

Related Questions