C:使用fgets()在动态缓冲区中存储字符串时调用realloc()后的奇怪行为

时间:2013-10-31 20:23:51

标签: c fgets dynamic-memory-allocation realloc

以下代码加载一个名为gasses.txt的文本文件,该文件有16个术语,每个术语各自独立,并将这些术语一次一个地存储在缓冲区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]);

}

输出看起来像这样。第一次重新分配内存后,存储在search_terms [0]中的字符串被破坏。

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
���

这是gasses.txt:

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

1 个答案:

答案 0 :(得分:3)

首次使用malloc for search_terms时,正确使用sizeof(char *) * number_search_terms作为大小。

但是,当您重新分配时,请改用number_search_terms。这个新大小是正确大小的1/4或1/8(取决于你的指针大小),所以你最终写到这个缓冲区的末尾。