目标是从文件中读入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];
但我不明白为什么。先谢谢你了!
答案 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;
}