我需要一个字符串数组,其中在编译时不知道数组的长度。我所做的是:
char **words;
words = malloc(capacity * sizeof(char *));
char nextword[MAX_LEN + 1];
while (true) {
if (num_entries == capacity) {
capacity += 5;
realloc(words, (sizeof(char *) * capacity));
}
printf("\nEnter a word: ");
fgets (nextword, MAX_LEN, stdin);
remove_newline(nextword);
if (strlen(nextword) == 0) break;
words[num_entries] = malloc(strlen(nextword + 1));
if (words[num_entries] == NULL) {
printf("\nout of space\n");
break;
}
strcpy(words[num_entries], nextword);
num_entries++;
这似乎可以扩展一次大小,但扩展后的第一个元素由于某种原因变为NULL
。第二次执行realloc
时出现错误:
"invalid next size"
。
答案 0 :(得分:7)
realloc
无法保证返回相同的内存块,因为最初从堆中分配的块可能没有足够的空间来容纳新请求的大小。在这种情况下,您将返回一个新的内存块,并将旧数据复制到其中。
您需要捕获每个循环上的返回值并使用它来检查您期望的数据,并检查它是否为0(如果realloc
无法完成)。
words = realloc(words,..)
是反模式 - 避免这种情况,因为如果realloc
失败,您的旧内存可能会丢失。
答案 1 :(得分:5)
您的代码几乎就在那里,只需要进行一些修改。要记住的一件重要事情是realloc
不会修改传递给它的值,并且不需要将指针返回到传递给它的同一块内存。 Here is a working example of using realloc。它非常简单,因此您只需按照示例即可修复代码。
char **more_words = realloc(words, capacity);
if (more_words) {
words = more_words;
} else {
// Do something about realloc failure
}