C 将指针解引用到指针数组
我试图理解指向指针数组的指针是如何工作的 我有以下结构C 将指针解引用到指针数组,c,arrays,pointers,C,Arrays,Pointers,我试图理解指向指针数组的指针是如何工作的 我有以下结构 typedef struct Array { int capacity; int size; void **items; } Array; 下面的函数为结构分配内存并返回指向它的指针 Array *createArray(int capacity) { Array *array = malloc(sizeof(Array *)); array->capacity = capacity;
typedef struct Array {
int capacity;
int size;
void **items;
} Array;
下面的函数为结构分配内存并返回指向它的指针
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;
}
现在,我的主要功能
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;
}
为什么我的程序seg只有在循环时才会出错?我是否缺少返回指针数组的基本信息 首先。问题似乎是您没有分配足够的内存
Array *array = malloc(sizeof(Array *));
只分配sizeof(void*)
字节,这可能小于sizeof(Array)
1
因此,当您尝试初始化返回的数组时,您正在访问未分配的内存,从而调用未定义的行为
要始终保持正确的内存量,请使用以下语法
Array *array = malloc(sizeof(*array));
这样可以确保分配的大小正确
秒。如果您看到值按预期打印,请将其归咎于未定义的行为。因为您的代码已经调用了它,所以在您调用之后它不会消失,而且问题会出现得更快、更晚或者永远不会出现,但它仍然存在。这是未定义行为最糟糕的地方,因为它是未定义的,你无法预测它何时或是否会发生
1事实上,它肯定更少,因为如果忽略填充,至少需要sizeof(void*)+2*sizeof(int)
应该是
Array *array = malloc(sizeof(Array));
sizeof(Array*)
只是指针的大小,而sizeof(Array)
是结构的大小Array
但是我不知道你的代码中到底发生了什么,因为它在array->items=items中出错了
在我的电脑里,也许你可以试试printf(“%d\n”)和((*(ptr[0]+9))->capacity)
获取地址并使用gdb
Array*Array=malloc(sizeof(Array*))计算出该地址中的确切内容代码>->Array*Array=malloc(sizeof(Array))
我有点惊讶,因为有一种情况下,您使用了永不出错的sizeof(*变量)
。例如Array*Array=malloc(sizeof(*Array))
永远不会错。即使您更改Array*Array代码>到数组****数组代码>!哦,对于一个函数来说,这是一个有趣的返回类型,更不用说它使用了一种奇怪的语言。@coderredoc-嘿,你介意详细解释一下为什么会修复它吗?我没有跟随…@random\u coder\u 101它不是你分配的指针,它是结构的一个实例sizeof(Array*)
等于任何指针的大小,甚至sizeof(void*)
,因此它根据平台和操作系统分配4或8个字节。但是你真的需要sizeof(Array)
字节来分配。也许最好一次分配M*N个条目,然后将这些块分割成单独的指针,给你一个连续的内存区域。单独分配可能会导致碎片化。不幸的是,这似乎没有任何区别。我的代码仍然以完全相同的方式进行分段。而且,这仍然不能解释为什么createHashTable中的循环正确地输出了值,对吗?@random_coder_101,你在使用什么操作系统?并删除可怕的返回类型,使用typedef
或其他什么!这只是一个建议。@IharobAlAsimi-macOS High Sierra v0.13.1你说的“我的电脑出了问题”是什么意思?你知道未定义的行为吗?我的意思是它是未定义的行为,所以我的编译器的结果不同于@random_coder_101。
Array *array = malloc(sizeof(*array));
Array *array = malloc(sizeof(Array *));
Array *array = malloc(sizeof(Array));