无法在结构中声明二维动态数组
Can't declare a 2D dynamic array in a struct
所以我有 2 个问题。
我正在尝试学习如何为二维数组动态分配内存。
这是一个工作代码,我首先想知道它是否正常,它是否有效,但我真的不知道我是否有内存泄漏或一些我没有看到的错误。
typedef struct Map Map;
struct Map
{
int width, height;
int** cases; // Not technically a 2D array but I use it like it in my code
};
int getMapValue(Map map, int x, int y);
void setMapValue(Map* map, int value, int x, int y);
void mallocMap(Map* map, int width, int height);
void freeMap(Map* map);
int main()
{
int l,h,i,j;
Map map;
printf("Width : ");
scanf("%d", &l);
printf("Height : ");
scanf("%d", &h);
map.width = l;
map.height = h;
mallocMap(&map, l, h); // allocate memory for the map
for(j = 0; j < map.height; j++)
for(i = 0; i < map.width; i++)
setMapValue(&map, i*j, i, j); // set some values
for(j = 0; j < map.height; j++)
for(i = 0; i < map.width; i++)
printf("%d ", getMapValue(map, j, i)); // read some values, works fine
freeMap(&map); // free memory
return 0;
}
void mallocMap(Map* map, int width, int height)
{
map->cases = malloc(sizeof(int) * width * height);
if (map->cases == NULL)
{
printf("Error\n");
exit(0);
}
}
void freeMap(Map* map)
{
free(map->cases);
}
int getMapValue(Map map, int x, int y)
{
return *(map.cases + y*map.height + x);
}
void setMapValue(Map* map, int value, int x, int y)
{
*(map->cases + y*map->height + x) = value;
}
那我有个问题。
我想添加一个 struct Player,其中有两个 Map 元素,如下所示:
struct Player
{
Map map[2];
};
但这会导致错误 array has incomplete element type
。显然是因为数组的大小设置不正确,我应该怎么做?
更新:我需要在Player结构之前写Map结构。
"incomplete type" 的问题很可能是因为您在定义 struct Map
之前定义了 struct Player
。
关于您的“二维”数组:使用 map->cases = malloc(sizeof(int) * width * height);
,您实际上在类似于 "real" 二维数组的布局中保留内存,而数据类型 int **cases
表示指向的指针指向 int 的指针。
所以如果你切换到 int *cases
,它应该可以工作。
请注意 cases
仍然不是 "real" 二维数组,因为您不能像 map->cases[3][4]
那样访问它(这会产生未定义的行为)。但是无论如何,您在 getter 和 setter 函数中自行计算偏移量,因此您的实现应该有效。
I really don't know if I have memory leaks or some errors I don't see.
是的。 @StephanLechner 指出,您在分配期间遇到了一些内存问题。
另外,您有一个算术错误,索引了错误的元素和超出数组边界的索引。您的 x
值范围从 0
到 width-1
,您的 y
值范围从 0
到 height-1
。每次递增 y
时,实际上是在移动数组中的 width
个元素。所以:
return *(map.cases + y*map.height + x);
应该是:
return *(map.cases + y*map.width + x);
所以我有 2 个问题。
我正在尝试学习如何为二维数组动态分配内存。 这是一个工作代码,我首先想知道它是否正常,它是否有效,但我真的不知道我是否有内存泄漏或一些我没有看到的错误。
typedef struct Map Map;
struct Map
{
int width, height;
int** cases; // Not technically a 2D array but I use it like it in my code
};
int getMapValue(Map map, int x, int y);
void setMapValue(Map* map, int value, int x, int y);
void mallocMap(Map* map, int width, int height);
void freeMap(Map* map);
int main()
{
int l,h,i,j;
Map map;
printf("Width : ");
scanf("%d", &l);
printf("Height : ");
scanf("%d", &h);
map.width = l;
map.height = h;
mallocMap(&map, l, h); // allocate memory for the map
for(j = 0; j < map.height; j++)
for(i = 0; i < map.width; i++)
setMapValue(&map, i*j, i, j); // set some values
for(j = 0; j < map.height; j++)
for(i = 0; i < map.width; i++)
printf("%d ", getMapValue(map, j, i)); // read some values, works fine
freeMap(&map); // free memory
return 0;
}
void mallocMap(Map* map, int width, int height)
{
map->cases = malloc(sizeof(int) * width * height);
if (map->cases == NULL)
{
printf("Error\n");
exit(0);
}
}
void freeMap(Map* map)
{
free(map->cases);
}
int getMapValue(Map map, int x, int y)
{
return *(map.cases + y*map.height + x);
}
void setMapValue(Map* map, int value, int x, int y)
{
*(map->cases + y*map->height + x) = value;
}
那我有个问题。 我想添加一个 struct Player,其中有两个 Map 元素,如下所示:
struct Player
{
Map map[2];
};
但这会导致错误 array has incomplete element type
。显然是因为数组的大小设置不正确,我应该怎么做?
更新:我需要在Player结构之前写Map结构。
"incomplete type" 的问题很可能是因为您在定义 struct Map
之前定义了 struct Player
。
关于您的“二维”数组:使用 map->cases = malloc(sizeof(int) * width * height);
,您实际上在类似于 "real" 二维数组的布局中保留内存,而数据类型 int **cases
表示指向的指针指向 int 的指针。
所以如果你切换到 int *cases
,它应该可以工作。
请注意 cases
仍然不是 "real" 二维数组,因为您不能像 map->cases[3][4]
那样访问它(这会产生未定义的行为)。但是无论如何,您在 getter 和 setter 函数中自行计算偏移量,因此您的实现应该有效。
I really don't know if I have memory leaks or some errors I don't see.
是的。 @StephanLechner 指出,您在分配期间遇到了一些内存问题。
另外,您有一个算术错误,索引了错误的元素和超出数组边界的索引。您的 x
值范围从 0
到 width-1
,您的 y
值范围从 0
到 height-1
。每次递增 y
时,实际上是在移动数组中的 width
个元素。所以:
return *(map.cases + y*map.height + x);
应该是:
return *(map.cases + y*map.width + x);