C: динамический массив указателей на массив структуры - PullRequest
6 голосов
/ 08 января 2010

У меня есть структура и двумерный массив этих структур:

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

room map[MAP_WIDTH][MAP_HEIGHT];

Мне нужен массив указателей этих структур. Следующий код компилируется, но я не получаю желаемый результат. Любая помощь? Меня это очень смущает, любое объяснение будет оценено

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

Ответы [ 6 ]

9 голосов
/ 08 января 2010

На самом деле, я думаю, что вы хотите

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

Это дает вам множество указателей на ваши комнаты.

1 голос
/ 08 января 2010

В вашем текущем коде rooms становится массивом room структур, а не массивом указателей. Если вам нужен массив указателей, каждый из которых указывает на ваш массив map, вам нужен еще один уровень косвенности:

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

(Или вы можете использовать sizeof (room *) как ваш код вместо sizeof *rooms; я предпочитаю писать так, чтобы избежать дублирования информации о типах.)

1 голос
/ 08 января 2010

Основная проблема, которую я вижу, заключается в том, что вы используете sizeof(room*). Это означает, что вы берете размер указателя на структуру, а это не то, что вам нужно. Вы хотите выделить размер структуры, поэтому сделайте это sizeof(room). Кроме того, используйте calloc в этом случае, а не malloc, поскольку вы в основном реализуете функциональность первого, умножая количество комнат на размер комнаты.

1 голос
/ 08 января 2010

Я уверен, что вы хотите

sizeof(room)

Вам необходимо выделить достаточно места для структуры. Вы выделяете только указатель.

Вам также может понадобиться выделять по-другому, если вы хотите 2D массив: см. здесь динамически распределяемый массив массивов в C

0 голосов
/ 08 января 2010

Если я правильно понимаю, вам нужен массив указателей на все значения room в map. Поскольку существует MAP_WIDTH*MAP_HEIGHT таких значений, нам нужно столько указателей:

room *rooms[MAP_WIDTH*MAP_HEIGHT];

Выше объявляется rooms как массив указателей.

Теперь, чтобы присвоить значения:

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

Мы в основном находим адрес каждого элемента в map и сохраняем его в правильной записи в rooms.

Это то, что вы хотели?

0 голосов
/ 08 января 2010

Вам нужно выделить место для указателей и для комнат , а затем инициализировать указатели так, чтобы они указывали на комнаты.

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];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...