free():在 tcache 2 中检测到双重释放 - c realloc 错误
free(): double free detected in tcache 2 - c realloc error
我正在尝试通过将指向单词的指针存储在 char ** 中来保存单词文件(最大长度为 100 个字符,但我不知道有多少)。我首先为 100 个指针分配内存并计算我保存的单词。如果文件中有超过 100 个单词,每次我从文件中读取一个新单词时,我都会开始使用 space 重新分配内存以获得一个指针。然后我为单词的实际字符分配 space。
// init wordlist for 100 words
char **mywords = malloc(100 * sizeof(char*));
int wordcount = 0;
char **word_pointer = mywords;
while(!feof(wordlist))
{
// dynamically reallocate more memory if we have more than 100 words
if (wordcount >= 100) {
realloc(mywords, sizeof(char*) * (wordcount+1));
}
char *new_word = *word_pointer;
new_word = malloc(101 * sizeof(char));
fgets(new_word, 101, wordlist);
printf("%s", new_word);
word_pointer++;
wordcount++;
}
我用超过 300 字的文件测试了代码,但出现错误
free(): double free detected in tcache 2
我猜是因为realloc之后的malloc?但我不确定如何修复它。
编辑
我将循环更改为:
// init wordlist for 100 words
char **mywords = malloc(100 * sizeof(char*));
int wordcount = 0;
char **word_pointer = mywords;
char *current_line = malloc(101 * sizeof(char));
int max_length = 101;
while(fgets(current_line, max_length, wordlist))
{
// dynamically reallocate more memory if we have more than 100 words
if (wordcount >= 100) {
mywords = realloc(mywords, sizeof(char*) * (wordcount+1));
}
*word_pointer = current_line;
word_pointer++;
wordcount++;
}
它运行没有错误。但我担心的是 word_pointer
会在调用 realloc()
之后指向 mywords 列表之前的位置,对吗?我该如何更改它以便在插入例如120 个字,realloc 发生了,它指向新的 mywords+120 以便我可以继续插入指针?
首先,您忽略了 realloc 的 return 值,它是指向已分配内存的指针。
在这种情况下,realloc 可能会扩展已经给定的内存块(如果可能的话),或者分配一个全新的内存块并复制给定的输入。
我觉得
mywords = realloc(mywords, sizeof(char*) * (wordcount+1));
应该可以解决问题。
此外,正如我提到的,重新分配并不是最佳选择。请注意,无论何时遇到新词 realloc 都必须在内存中找到一个位置并复制整个数据块。因此,假设给定一个包含 300 个单词的文件,您的程序将复制您的数组 200 次。
我认为最好先扫描文件,统计所有单词,然后使用 fseek 将指示符移动到开头。之后为你的单词分配数组并扫描文件。
在编辑原始问题后我想出了解决方案。我只需要在 realloc()
的调用下方添加行 word_pointer = mywords + wordcount;
感谢您的帮助!
我正在尝试通过将指向单词的指针存储在 char ** 中来保存单词文件(最大长度为 100 个字符,但我不知道有多少)。我首先为 100 个指针分配内存并计算我保存的单词。如果文件中有超过 100 个单词,每次我从文件中读取一个新单词时,我都会开始使用 space 重新分配内存以获得一个指针。然后我为单词的实际字符分配 space。
// init wordlist for 100 words
char **mywords = malloc(100 * sizeof(char*));
int wordcount = 0;
char **word_pointer = mywords;
while(!feof(wordlist))
{
// dynamically reallocate more memory if we have more than 100 words
if (wordcount >= 100) {
realloc(mywords, sizeof(char*) * (wordcount+1));
}
char *new_word = *word_pointer;
new_word = malloc(101 * sizeof(char));
fgets(new_word, 101, wordlist);
printf("%s", new_word);
word_pointer++;
wordcount++;
}
我用超过 300 字的文件测试了代码,但出现错误
free(): double free detected in tcache 2
我猜是因为realloc之后的malloc?但我不确定如何修复它。
编辑
我将循环更改为:
// init wordlist for 100 words
char **mywords = malloc(100 * sizeof(char*));
int wordcount = 0;
char **word_pointer = mywords;
char *current_line = malloc(101 * sizeof(char));
int max_length = 101;
while(fgets(current_line, max_length, wordlist))
{
// dynamically reallocate more memory if we have more than 100 words
if (wordcount >= 100) {
mywords = realloc(mywords, sizeof(char*) * (wordcount+1));
}
*word_pointer = current_line;
word_pointer++;
wordcount++;
}
它运行没有错误。但我担心的是 word_pointer
会在调用 realloc()
之后指向 mywords 列表之前的位置,对吗?我该如何更改它以便在插入例如120 个字,realloc 发生了,它指向新的 mywords+120 以便我可以继续插入指针?
首先,您忽略了 realloc 的 return 值,它是指向已分配内存的指针。
在这种情况下,realloc 可能会扩展已经给定的内存块(如果可能的话),或者分配一个全新的内存块并复制给定的输入。
我觉得
mywords = realloc(mywords, sizeof(char*) * (wordcount+1));
应该可以解决问题。
此外,正如我提到的,重新分配并不是最佳选择。请注意,无论何时遇到新词 realloc 都必须在内存中找到一个位置并复制整个数据块。因此,假设给定一个包含 300 个单词的文件,您的程序将复制您的数组 200 次。
我认为最好先扫描文件,统计所有单词,然后使用 fseek 将指示符移动到开头。之后为你的单词分配数组并扫描文件。
在编辑原始问题后我想出了解决方案。我只需要在 realloc()
word_pointer = mywords + wordcount;
感谢您的帮助!