无法在结构中声明2D动态数组

时间:2017-11-14 21:44:26

标签: c multidimensional-array dynamic malloc dynamic-allocation

所以我有2个问题。

我正在尝试学习如何为2D数组动态分配内存。 这是一个有效的代码,我首先想知道它是否很好,它有效,但我真的不知道我是否有内存泄漏或一些我不知道的错误。

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。显然,由于数组的大小没有正确设置,我应该如何使用呢?

更新:我需要在播放器结构之前编写Map结构。

2 个答案:

答案 0 :(得分:2)

&#34;不完整类型的问题&#34;很可能是因为您在定义struct Player之前定义了struct Map

关于您的&#34; 2D&#34; -Array:使用map->cases = malloc(sizeof(int) * width * height);,您实际上会在类似于&#34; real&#34;的布局中保留内存。 2D数组,而数据类型int **cases表示指向int的指针。 因此,如果您切换到int *cases,它应该可以正常工作。

请注意,cases仍然不是真实的&#34; 2D-Array,因为您不允许像map->cases[3][4]那样访问它(这会产生未定义的行为)。但是你无论如何都要在getter和setter函数中自己计算偏移量,所以你的实现应该可行。

答案 1 :(得分:1)

  

我真的不知道我是否有内存泄漏或一些我不知道的错误。

是。在@StephanLechner指出的分配过程中,您遇到了一些内存问题。

此外,您有一个算术错误,它会索引数组范围之外的错误元素和索引。您的x值的范围从0width-1,而您的y值的范围从0height-1。每次增加y时,实际上是在数组中移动width个元素。所以:

return *(map.cases + y*map.height + x);

应该是:

return *(map.cases + y*map.width + x);