我试图理解指针数组的指针是如何工作的。
我有以下结构
typedef struct Array {
int capacity;
int size;
void **items;
} Array;
和以下函数为struct分配内存并返回指向它的指针
Array *createArray(int capacity) {
Array *array = malloc(sizeof(Array *));
array->capacity = capacity;
array->size = 0;
void **items = malloc(sizeof(void *) * array->capacity * sizeof *items);
if(items == NULL) {
exit(1);
}
array->items = items;
return array;
}
现在,我想初始化一个指向此结构的指针数组。我就是这样做的
Array *(*createHashTable(int size))[10] {
Array *array[10];
int i = 0;
for(i = 0; i < size; i++) {
array[i] = createArray(size);
}
Array *(*ptr)[10] = &array;
for(i = 0; i < size; i++) {
printf("%d\n", (*(ptr[0] + i))->capacity);
}
return ptr;
}
print语句给出了我的期望:
10
10
10
10
10
10
10
10
10
10
现在,我的主要功能
int main(int argc, char *argv[]) {
Array *(*ptr)[10] = createHashTable(10);
printf("%d\n", (*(ptr[0]+9))->capacity);
return 0;
}
到目前为止,一切对我都有意义,main
中的printf语句正常工作。然而,令我困惑的部分是我在main
函数中放置一个for循环,如此
int main(int argc, char *argv[]) {
Array *(*ptr)[10] = createHashTable(10);
int i = 0;
for(i = 0; i < 10; i++) {
printf("%d\n", (*(ptr[0] + i))->capacity);
}
return 0;
}
我得到以下输出,
10
10
Segmentation fault: 11
为什么我的程序只在我循环时才会出错?我是否遗漏了一些关于返回指向指针数组的指针的基本知识?
答案 0 :(得分:2)
<强>第一即可。问题似乎是你没有分配足够的内存,
Array *array = malloc(sizeof(Array *));
仅分配sizeof(void *)
字节,并且可能小于sizeof(Array)
1
因此,当您尝试初始化返回的array
时,您正在访问未分配的内存,从而调用未定义的行为。
要始终使用大量内存,请使用以下语法
Array *array = malloc(sizeof(*array));
这样可以确保分配正确的大小。
<强>第二即可。如果您看到值按预期打印,请将其归咎于未定义的行为。因为你的代码已经调用了它,所以它不会在你执行之后消失,并且问题将会出现得更早,更晚或者永远不会出现,但它仍然存在。这是关于未定义行为的最糟糕的事情,因为它未定义,你无法预测它何时或是否会发生。
1 事实上,它确实少了,因为你至少需要sizeof(void *) + 2 * sizeof(int)
,就是你忽略了填充。
答案 1 :(得分:1)
Array *array = malloc(sizeof(Array *));
应该是
Array *array = malloc(sizeof(Array));
sizeof(Array *)
只是指针的大小,而sizeof(Array)
是结构Array
的大小。
但我不确切知道您的代码中发生了什么,因为我的计算机array->items = items;
出现了问题,也许您可以尝试printf("%d\n", &((*(ptr[0]+9))->capacity));
获取地址并找出确切的结果在此地址中显示gdb
。