加倍双指针数组的大小?

时间:2014-03-23 04:38:42

标签: c arrays pointers

目标是从文件中读入105个单词并将它们分配给数组。数组初始化为

char **array = (char**)malloc(*capacity * sizeof(char*)); 

其中容量设置为50.

我试图这样做,所以当读入50个单词并且第51个准备就绪时,会调用此函数。 数组的初始分配应该是50个指针的空间。如果数组已满(即wordCount等于当前容量),并且插入了一个单词,我将使数组的容量加倍(即malloc一个当前大小的两倍的新数组,复制字符串进入新分配的数组的前半部分,并释放旧数组使用的空间。我不允许使用realloc。我只想帮助修复使用我的方法执行此操作的方法。请不要建议替代方法。

所以我一直遇到分段错误而且我不明白为什么。有什么建议?

int doubleArraySize(char ***array, int count, int *capacity){ 
    char **temp = (char**)malloc(*capacity * sizeof(char*)); 
    if (temp = NULL){ 
        return -1; 
    } 

    int i = 0; 
    while(i<count){ 
        temp[i] = *array[i]; 
        i++; 
    } 

    i = 0; 
    while(i<count){ 
        free(*array[i]); 
        i++; 
    } 

    free(*array); 
    *array = temp; 
    return 0; 
}

是的,我不被允许使用realloc。我被特别告知要创建一个双倍大小的新数组,然后将元素复制到上半部分然后释放旧元素。同样在我正在使用的调试器中,它说问题在于行

temp[i] = *array[i];

但我不明白为什么。先谢谢你了!

2 个答案:

答案 0 :(得分:4)

*array[i]更改为(*array)[i]中的temp[i] = *array[i]; 下标运算符[]的优先级高于解除引用运算符*,因此(*array)[i]指定char*数组的第i个元素,而*array[i]则取消引用char**数组的第i个元素。根据程序的逻辑,前者是你真正想要的,所以括号不能省略。

你不应该free任何一个(*array)[i],因为你实际上将它们存储在新分配的数组中。只需free(*array)即可。

答案 1 :(得分:1)

首先,不要施放malloc的结果。它没有任何好处,如果您忘记包含标题stdlib.h,可能会导致错误。阅读详情 - Do I cast the result of malloc?

现在,用于将旧数组复制到新数组的语句存在问题 -

temp[i] = *array[i];

数组下标运算符[]的优先级高于解除引用运算符*。因此,上述内容与 -

相同
temp[i] = *(array[i]);

array的类型为char ***,并指向char **类型的对象数组。 array[i]求值为*(array + i),它会执行非法内存访问,从而调用未定义的行为。因此,您应该将语句更改为

temp[i] = (*array)[i];

表示首先取消引用array,然后获取i指向的缓冲区中的array元素。我建议使用标准库函数memcpy将旧数组复制到新数组中。此外,要释放一块动态分配的缓冲区,您只需要传递缓冲区的基址,即可释放整个块。

#include <string.h>
#include <stdlib.h>

int doubleArraySize(char ***array, int count, int *capacity) { 
    char **temp = malloc(*capacity * sizeof *temp); 
    if(temp = NULL){ 
        return -1; 
    } 

    memcpy(temp, *array, count * sizeof **array);

    free(*array); 
    *array = temp; 
    return 0; 
}