realloc не выделяет память для следующей структуры - PullRequest
0 голосов
/ 01 июня 2019

Мне нужно динамически создать массив структур, и я не знаю размер при выполнении команды malloc.Поэтому я подумал, что могу использовать realloc каждый раз, когда мне нужна другая структура!Например, этот код:

main:

    int main(void) {

    flights *flight_list = NULL;
    int numFlights = 0;

    numFlights = load_flights(&flight_list);

    /* output flights. Problem: Only first flight is there, the second is not allocated! */

Вот функция:

short load_flights(flights **flight_list) {

    flight_list[0] = calloc(1, sizeof(flights));
    flight_list[0]->price = 69;

    flight_list[0] = realloc(*flight_list, sizeof(flights)*2);
    flight_list[1]->price = 70;

    return 2; //num of flights-structs

Проблема в том, что на самом деле должны быть созданы 2 элемента, но только 1элемент есть - проверьте этот скриншот отладки:

Debugging Screenshot

Как видите, flight_list[0] есть, но flight_list[1] нет!Но realloc должен делать эту работу?

Я что-то не так понимаю?

Ответы [ 2 ]

2 голосов
/ 01 июня 2019

В этой строке есть ошибка:

flight_list[1]->price = 70;

Оба [] и -> указатели разыменования. a[b] эквивалентно *(a+b) и a->b эквивалентно (*a).b. Поэтому ваша строка означает:

(**(flight_list + 1)).price = 70;

Однако flight_listload_flights) - это указатель на переменную flight_list в main! В контексте main вы вычисляете &flight_list + 1, который является недопустимым указателем: вы получаете содержимое памяти, которое находится рядом с локальной переменной.

Правильный код будет:

(*(*flight_list + 1)).price = 70;

*flight_list - указатель, возвращаемый realloc. Здесь мы можем сделать шаг вперед в динамическом массиве.

Мы также можем написать это как:

(*flight_list)[1].price = 70;
0 голосов
/ 01 июня 2019

Ваш flight_list представляет собой массив указателей на указатели рейсов.

С помощью flight_list[0] = realloc(*flight_list, sizeof(flights)*2); вы выделяете место для двух полетов для элемента flight_list[0], но сам flight_list остается неизменным. На самом деле, нет кода, который бы выделил какое-либо пространство для flight_list, но, возможно, вы просто пропустили этот код в своем примере.

Если вам нужна строка кода realloc, вы должны следить за этими местами памяти в отладчике: flight_list[0][0] для первого полета и flight_list[0][1] для второго.

...