简体   繁体   中英

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!

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).

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