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