C传递可变大小的二维数组来起作用

我正在尝试重构我的代码以使其更好/更具可读性所以我正在尝试更改2-D变量数组分配如下

// OLD CODE int **map; map = calloc(number, sizeof(int *)); if (!(map)) { free(map); return 1; } for (int i = 0; i = 0) { free(map[i]); } free(map); return 1; } } // NEW CODE int (*map)[number] = malloc(sizeof (int[number][number])); if (!(map)){ free(map); return 1; } 

问题是我使用map的所有函数都采用int **map并且通过更改int **map的声明,就像我所做的那样,IDE告诉我incorrect type int[]* instead of int**我应该使用什么而不是int** ? 在函数声明中使用int[]* map告诉我can't resolve variable map

原来以下代码不是C99替代@MM ,而是GCC扩展。

未记载的GCC扩展:结构中的VLA


作为C99 GCC扩展替代int (*map)[number] = malloc(sizeof (int[number][number])); 为了简化代码并保持与现有函数集的兼容性,使用1 *alloc()调用分配所需的所有内存。

这确实要求当代码完成map ,所有内存都是free(map) ,一个free(map) 。 此外, map[]各行不能再重新分配,但可以在map[]交换。

 int **map_allocate(size_t row, size_t column) { struct { int *ip[row]; // Array of pointers, followed by a ... int i[row][column]; // 2D array of int } *u; u = calloc(1, sizeof *u); if (u == NULL) { return NULL; } for (size_t i = 0; iip[i] = u->i[row]; } return &u->ip[0]; } 

注意:没有转换和字段i[][]正确对齐。

与其他答案不同,使用标准代码的一个分配有点棘手,因为需要确保指针和int的组合内存分配需要满足对齐要求的exception情况下的对齐问题超过指针对齐问题。 这更long long如下所示更容易显示。

如果这使“代码更容易阅读”留给OP的判断。

 #include  #include  long long **map_allocate_ll(size_t row, size_t column) { long long **map; long long *ints; size_t pointers_sz = sizeof *map * row; // extend pointer size to `*ints` boundary pointers_sz = (pointers_sz + sizeof *ints - 1)/sizeof *ints * sizeof *ints; size_t ints_sz = sizeof *ints * row * column; printf("psize %zu, isize %zu\n", pointers_sz, ints_sz); map = calloc(1, pointers_sz + ints_sz); if (map == NULL) { return NULL; } ints = (void*) ((char*) map + pointers_sz); printf("map %p\n", (void *) map); for (size_t i = 0; i 

样本输出

 psize 24, isize 120 map 0x80081868 map[0] 0x80081880 map[1] 0x80081898 map[2] 0x800818b0 map[3] 0x800818c8 map[4] 0x800818e0