bashful_creature
bashful_creature

Reputation: 1

Freeing array of char pointers - only works when I have an even number of strings...?

Having a super strange problem in C that I think is related to string memory management but I've poured through this code and can't tell what I'm doing wrong. I'm setting up an array of pointers to strings, where each string in the array is a token broken up from strtok(), which operates on a line made from getline using stdin.

I've been able to break apart the tokens, store them, and print the array with no problem. I just am having trouble freeing each individual pointer afterwards. I get an error message saying "invalid pointer", but oddly enough, it's only when I input an odd number of words in my original string. Even when I input an odd number of words in my string, it still breaks them apart into tokens and stores them in the array, its just the memory freeing that's failing.

here's a snippet of what I have:

char *line = NULL;
size_t len = 0;
getline(&line, &len, stdin);

char *token = strtok(line, " \n");

char **parsed = malloc(sizeof(char*));
if(parsed == NULL){
    printf("ruh roh scoob\n");
}

int numList = 0;
while(token!=NULL){
    numList++;
    parsed = realloc(parsed, sizeof(char*)*numList);
    if(parsed == NULL){
        printf("realloc failed :(\n");
    }

    int tokenLen = strlen(token);
    parsed[numList-1] = malloc(sizeof(char)*tokenLen);
    if(parsed[numList-1] == NULL){
        printf("ruh roh raggy\n");
    }

    strcpy(parsed[numList-1], token);

    token = strtok(NULL, " \n");
}
parsed[numList] = NULL;

for(int i = 0; i <= numList; i++){
    printf("%d-%s", i, parsed[i]);
}
printf("\n");

for(int j = 0; j < numList; j++){
    free(parsed[j]);
} 

I thought I was allocating memory correctly and storing the data from my token pointers into the new pointers correctly but perhaps I was wrong. Any advice would be appreciated!

Upvotes: 0

Views: 48

Answers (1)

user5677297
user5677297

Reputation:

Inside the loop you call:

strcpy(parsed[numList-1], token);

This needs at least strlen(token) + 1 bytes, but you're allocating one too few:

int tokenLen = strlen(token);
parsed[numList-1] = malloc(sizeof(char)*tokenLen);

So the strcpy writes past end of buffer, probably corrupting malloc metadata on a random basis. Note that you may get away with a write past end of buffer, because malloc rounds up the allocation amount, both to avoid memory fragmentation and to ensure that dynamically allocated buffers keep proper alignment (for better performance).

Upvotes: 1

Related Questions