简体   繁体   中英

C: Weird behavior after calling realloc() when using fgets() to store strings in a dynamic buffer

The following code loads in a text file called gasses.txt that has 16 terms, each on its own line, and stores these terms one at a time in the buffer search_terms.

#define MAX_LINE_LEN 40
FILE *dict_fp;
int term_len;
int j;

size_t number_search_terms = 10;
int i;
char **search_terms = malloc(sizeof(char *) * number_search_terms);
for (i=0; i < number_search_terms; i++)
    search_terms[i] = malloc(MAX_LINE_LEN);

dict_fp = fopen("gasses.txt", "r");
for (i=0; fgets(search_terms[i], MAX_LINE_LEN, dict_fp) != NULL; i++){

    // get rid of the newline.
    term_len = strlen(search_terms[i]);
    search_terms[i][term_len-1] = 0;

    // resize buffer when it gets full
    if (i == number_search_terms-1){
        number_search_terms *= 2;
        search_terms = realloc(search_terms, number_search_terms);      
        for (j = number_search_terms/2; j < number_search_terms; j++)
            search_terms[j] = malloc(MAX_LINE_LEN);
    }

    printf("%s\n", search_terms[i]);

    printf("%s\n\n", search_terms[0]);

}

The output looks like this. After the first memory reallocation, the string stored in search_terms[0] gets corrupted.

nitrogen
nitrogen

oxygen
nitrogen

argon
nitrogen

carbon dioxide
nitrogen

neon
nitrogen

helium
nitrogen

methane
nitrogen

krypton
nitrogen

hydogen
nitrogen

nitrous oxide
���

xenon
���

ozone
���

nitrogen dioxide
���

iodine
���

ammonia
���

water vapour
���

This is gasses.txt:

oxygen
argon
carbon dioxide
neon
helium
methane
krypton
hydogen
nitrous oxide
xenon
ozone
nitrogen dioxide
iodine
ammonia
water vapour

When you first malloc for search_terms, you correctly use sizeof(char *) * number_search_terms for the size.

However, when you realloc, you use number_search_terms instead. This new size is 1/4 or 1/8 the correct size (depending on your pointer size) and so you end up writing past the end of this buffer.

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