pistacchio
pistacchio

Reputation: 58863

C: Dynamic array of pointers to array of structure

I have a structure and a bidimensional array of those structs:

typedef struct {
char exit_n;
char exit_s;
char exit_w;
char exit_e;
} room;

room map[MAP_WIDTH][MAP_HEIGHT];

I need an array of pointers those structs. The following code compiles, but I don't get the wanted result. Any help? This is getting really confused to me, any explanation would be appreciated

room *rooms;
rooms = (room*)malloc(sizeof(room*) * ROOM_NUM);
[..]
rooms[n] = map[room_x][room_y];
[..]

Upvotes: 6

Views: 4941

Answers (6)

Alok Singhal
Alok Singhal

Reputation: 96101

If I understand correctly, you want an array of pointers to all the room values in map. Since there are MAP_WIDTH*MAP_HEIGHT such values, we need that many pointers:

room *rooms[MAP_WIDTH*MAP_HEIGHT];

The above declares rooms as an array of pointers.

Now, to assign the values:

size_t i;
size_t j;

for (i=0; i < MAP_WIDTH; ++i)
    for (j=0; j < MAP_HEIGHT; ++j)
        rooms[i*MAP_HEIGHT+j] = &map[i][j];

We basically find the address of each element in map, and store it in the correct entry in rooms.

Is this what you wanted?

Upvotes: 0

John Knoeller
John Knoeller

Reputation: 34128

You need to allocate space for the pointers and for the rooms and then initialize the pointers to point to the rooms.

room *rooms; 
room **prooms;
rooms = (room*)malloc((sizeof(room) + sizeof(room*)) * ROOM_NUM); 
prooms = (room**)(&rooms[ROOM_NUM]);
for (int ii = 0; ii < ROOM_NUM; ++ii)
   prooms[ii] = &rooms[ii];

Upvotes: 0

Richard Pennington
Richard Pennington

Reputation: 19965

Actually, I think you want

room** rooms;
rooms = (room**)malloc(sizeof(room*) * ROOM_NUM);
[..]
rooms[n] = &map[room_x][room_y];

This gives you an array of pointers to your rooms.

Upvotes: 9

JaakkoK
JaakkoK

Reputation: 8387

In your current code, rooms becomes an array of room structures, not an array of pointers. If you want an array of pointers that each point to your map array, you need another layer of indirection:

room** rooms = malloc(ROOM_NUM * sizeof *rooms);
// ...
rooms[n] = &map[room_x][room_y];

(Or you can use sizeof (room *) like your code has instead of sizeof *rooms; I prefer to write it that way to avoid duplicating type information.)

Upvotes: 1

avpx
avpx

Reputation: 1922

The major issue I see is that you are using sizeof(room*). This means that you are taking the size of a pointer to a structure, which is not what you want. You want to allocate the size of the structure, so make that sizeof(room). Also, use calloc in this case, not malloc, as you are basically implementing the former's functionality by multiplying the number of rooms by the size of the room.

Upvotes: 1

Nick Van Brunt
Nick Van Brunt

Reputation: 15464

I'm am pretty sure you want

sizeof(room)

You need to allocate enough space for the struct. You are only allocating for a pointer.

You also may need to allocate differently if you want a 2D array: see here dynamic allocating array of arrays in C

Upvotes: 1

Related Questions