2011-12-01 37 views
1

我需要一个字符串数组,其中在编译时不知道数组的长度。我所做的是:动态调整字符串数组的大小

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

回答

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 
} 
+0

感谢您的链接。它非常有帮助。 – Wcrousse

+0

链接很好,但是在计算器中,如果链接不再工作,则需要直接在此处显示解决方案。 –

+0

@YohanObadia代码不是必需的,只要解释足以找出问题所在。解决方法是通过解释问题所在(我的意思是“realloc不会修改您传递给它的值”部分)。 – dasblinkenlight

7

realloc不能保证给你回相同的内存块,因为最初从堆中分配的块可能没有足够的空间来容纳你新的请求大小。在这种情况下,您将返回一个新的内存块,并将您的旧数据复制到该内存块。

您需要捕获每个循环的返回值,并使用它来检查您所期望的数据,并检查它是否为0(如果realloc无法完成)。

words = realloc(words,..) 

是一个反模式 - 避免这种情况,因为旧的记忆可能会丢失,如果realloc失败。