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

时间:2017-03-06 20:45:17

标签: c malloc

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

// OLD CODE
int **map;
        map = calloc(number, sizeof(int *));
        if (!(map)) {
            free(map);
            return 1;
        }
        for (int i = 0; i < number; i++) {
            map[i] = calloc(number, sizeof(int));
            if (!(map[i])) {
                while (--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并通过更改地图声明,就像我所做的那样,IDE告诉我incorrect type int[]* instead of int** 我应该使用什么而不是int**?在函数声明中使用int[]* map告诉我can't resolve variable map

2 个答案:

答案 0 :(得分:0)

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

Undocumented GCC Extension: VLA in struct

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

这确实要求在使用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; i<row; i++) {
    u->ip[i] = u->i[row];
  }
  return &u->ip[0];
}

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

答案 1 :(得分:0)

使用标准代码unlike the other answer的一个分配,有点棘手,因为需要确保指针和int的组合内存分配需要满足{{0}的异常情况下的对齐问题{1}}对齐要求超过指针对齐要求。使用int更容易显示,如下所示。

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

long long

示例输出

#include <stdlib.h>
#include <stdio.h>

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<row; i++) {
    map[i] = &ints[i * column];
    printf("map[%zu] %p\n", i, (void *) map[i]);
  }
  return map;
}

int main() {
  free(map_allocate_ll(5,3));
}