Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将指针解引用到指针数组_C_Arrays_Pointers - Fatal编程技术网

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));