Оператор sizeof
вычисляется во время компиляции. Его нельзя использовать для определения размера динамически размещаемого массива.
C накладывает бремя отслеживания фактического размера массива на программиста. Вы можете сохранить отдельную переменную count, но поскольку фактический массив и его размер принадлежат друг другу, полезно хранить их рядом друг с другом в структуре:
typedef struct Flight Flight;
typedef struct Flights Flights;
struct Flight {
char airline[4];
int number;
char dest[4];
};
struct Flights {
Flight *flight;
int count;
};
Вместо того, чтобы работать с массивом, работайте с the struct:
void add_flight(Flights *fl,
const char *airline, int number, const char *dest)
{
int n = fl->count++; // n is old count; fl->count is new count
fl->flight = realloc(fl->flight,
(fl->count + 1) * sizeof(*fl->flight));
snprintf(fl->flight[n].airline, 4, "%s", airline);
snprintf(fl->flight[n].dest, 4, "%s", dest);
fl->flight[n].number = number;
}
Инициализировать структуру рейсов с помощью NULL
с нулевым счетом и не забудьте освободить использованную память, когда закончите:
int main(void)
{
Flights fl = {NULL, 0};
add_flight(&fl, "AF", 5512, "CDG");
add_flight(&fl, "AA", 1100, "ATL");
add_flight(&fl, "LH", 6537, "FRA");
add_flight(&fl, "BA", 8821, "LHR");
add_flight(&fl, "IB", 1081, "EZE");
print_flights(&fl);
free(fl.flight);
return 0;
}
Вы можете увидеть это в действии здесь . Некоторые наблюдения:
- Нет необходимости различать guish между добавлением первого и последующих полетов, поскольку
realloc(NULL, size)
ведет себя точно так же, как malloc(size)
. - Это не очень эффективно перераспределять память для каждого добавленного элемента. Вместо этого вы выбираете подходящий начальный размер массива, например 4 или 8, а затем удваиваете размер при достижении предела. Это означает, что выделенный размер и количество могут отличаться, и вам нужно дополнительное поле
memsize
в структуре ваших рейсов. - Приведенный выше код основан на ручной инициализации и уничтожении. Обычно вы будете писать функции «конструктор» и «деструктор», чтобы сделать это для вас.