Reputation: 1538
So I have 2 questions.
I'm trying to learn how to dynamically allocate memory for 2D arrays. Here is a working code, I first want to know if it's fine, it works but I really don't know if I have memory leaks or some errors I don't see.
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;
}
Then I have a problem. I want to add a struct Player which has two Map elements in it like so :
struct Player
{
Map map[2];
};
But this results in an error array has incomplete element type
. Apparently it's because of the size of the array that isn't set correctly, how should I make this work ?
Update : I needed to write the Map structure before the Player structure.
Upvotes: 0
Views: 58
Reputation: 2866
I really don't know if I have memory leaks or some errors I don't see.
Yes. You have some memory problems during the allocation that has been pointed out by @StephanLechner.
Also, you have an arithmetic error that indexes the wrong elements and indexes outside the bounds of your array. Your x
value ranges from 0
to width-1
and your y
value ranges from 0
to height-1
. Each time you increment y
you are actually moving width
elements in the array. So:
return *(map.cases + y*map.height + x);
Should be:
return *(map.cases + y*map.width + x);
Upvotes: 1
Reputation: 35154
The problem with the "incomplete type" is very likely because you define struct Player
before having defined struct Map
.
Concerning your "2D"-Array: With map->cases = malloc(sizeof(int) * width * height);
, you actually reserve memory in a layout similar to a "real" 2D-array, whereas datatype int **cases
denotes a pointer to pointer to an int.
So if you switch to int *cases
, it should work.
Note that cases
still is not a "real" 2D-Array, since you are not allowed to access it like map->cases[3][4]
(this would yield undefined behaviour). But you calculate the offsets on your own in the getter and setter functions anyway, so your implementation should work.
Upvotes: 2