Entonces tengo 2 preguntas.

Estoy tratando de aprender cómo asignar memoria dinámicamente para matrices 2D. Aquí hay un código que funciona, primero quiero saber si está bien, funciona pero realmente no sé si tengo pérdidas de memoria o algunos errores que no veo.

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;
}

Entonces tengo un problema. Quiero agregar un struct Player que tiene dos elementos Map así:

struct Player
{
    Map map[2];
};

Pero esto resulta en un error array has incomplete element type. Aparentemente, es debido al tamaño de la matriz que no está configurado correctamente, ¿cómo debo hacer que esto funcione?

Actualización: necesitaba escribir la estructura del mapa antes que la estructura del reproductor.

0
Drakalex 15 nov. 2017 a las 00:44

2 respuestas

La mejor respuesta

El problema con el "tipo incompleto" es muy probable porque define struct Player antes de haber definido struct Map.

Con respecto a su matriz "2D": con map->cases = malloc(sizeof(int) * width * height);, en realidad reserva memoria en un diseño similar a una matriz 2D "real", mientras que el tipo de datos int **cases denota un puntero a un puntero a un int. Entonces, si cambia a int *cases, debería funcionar.

Tenga en cuenta que cases todavía no es una matriz 2D "real", ya que no se le permite acceder a ella como map->cases[3][4] (esto produciría un comportamiento indefinido). Pero calcula las compensaciones por su cuenta en las funciones getter y setter de todos modos, por lo que su implementación debería funcionar.

2
Stephan Lechner 14 nov. 2017 a las 22:00

Realmente no sé si tengo pérdidas de memoria o algunos errores que no veo.

Si. Tiene algunos problemas de memoria durante la asignación que ha señalado @StephanLechner.

Además, tiene un error aritmético que indexa los elementos e índices incorrectos fuera de los límites de su matriz. Tu valor de x varía de 0 a width-1 y tu valor de y varía de 0 a height-1. Cada vez que incrementa y, en realidad está moviendo width elementos en la matriz. Entonces:

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

Debe ser:

return *(map.cases + y*map.width + x);
1
MFisherKDX 14 nov. 2017 a las 22:13