struct c динамически выделяет память

Я использую структуру и хочу инициализировать максимум 10 портов. Однако, когда программа работает, это может быть намного меньше, мы не знаем этого до времени выполнения. Однако это будет макс. Я никогда раньше не создавал такую ​​структуру, так как обычно динамически выделяю память с помощью calloc и delcare, например, *ports в качестве типа значения.

Однако я не могу этого понять

*ports[MAX_PORTS]. Am I creating 10 pointers that point to port objects?

А также

*ports = (struct port_t*) calloc(2, sizeof(*ports)); 

Похоже, я выделяю один указатель, который указывает на 2 объекта порта, выделенные в свободном хранилище?

Я не могу понять, почему я использую оператор точки со стрелкой? порты[0]->port_id = 20; printf("port_id: %d\n", ports[0]->port_id);

#include <stdio.h>
#include <stdlib.h>

#define MAX_PORTS 10

struct port_t
{
    int port_id;
    char name;
} *ports[MAX_PORTS];

int main(void)
{
    *ports = (struct port_t*) calloc(2, sizeof(*ports));

    ports[0]->port_id = 20;

    printf("port_id: %d\n", ports[0]->port_id);

    return 0;
}

обычно то, что я сделал в прошлом, это:

struct port_t
{
    int port_id;
    char name;
} *ports;

ports = (struct port_t*) calloc(2, sizeof(*ports));

А затем назначьте одно из следующих ниже. Однако предыдущий программист объявил все так же, как я показал вверху, поэтому я не могу ничего изменить.

ports[0].port_id = 10;
ports->port_id = 10;

Большое спасибо за любые предложения,


person ant2009    schedule 06.03.2009    source источник


Ответы (3)


*ports[MAX_PORTS]. Am I creating 10 pointers that point to port objects?

Да, вы делаете массив из десяти указателей

*ports = (struct port_t*) calloc(2, sizeof(*ports));

...но эта строка - чепуха. Это то же самое, что:

ports[0] = (struct port_t*) calloc(2, sizeof(port_t));

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

Для такой мелочи гораздо разумнее было бы сделать десять портов, но не использовать их все:

#define MAX_PORTS 10

struct port_t
{
    int port_id;
    char name;
} ports[MAX_PORTS];

/* number of ports in use */
int numPorts = 0;

int main(void)
{
    numPorts = 3;
    for (int i=0; i<numPorts; i++) {
     ports[i].port_id = i;
     printf("port_id %d: %d\n", i, ports[i].port_id);
    }
    return 0;
}
person Jimmy J    schedule 06.03.2009
comment
Не могу проголосовать достаточно. Использование динамического распределения для чего-то такого пустякового, как 10 port_t, излишне усложняет код. - person jdizzle; 05.03.2010

Ваш первый блок кода имеет

struct port_t
{
    int port_id;
    char name;
} *ports[MAX_PORTS];

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

ports[0]->port_id

вы разыменовываете первый указатель в массиве. Существует также некоторое уродство, связанное с размером того, что вы на самом деле вызываете. На самом деле вы заменяете свой массив из 10 массивом из 2. То, что у вас есть, обычно уродливо и подвержено ошибкам.

Я считаю, что ваши намерения больше похожи на:

struct port_t
{
    int port_id;
    char name;
} *ports;

int main(void)
{
    *ports = (struct port_t*) calloc(2, sizeof(*ports));

    ports[0].port_id = 20;

    printf("port_id: %d\n", ports[0].port_id);

    return 0;
}

Поскольку вы используете C99, вы можете избежать calloc()/malloc(), если вы действительно этого хотите, используя объявление массива переменных C99.

port_t array_on_mains_stack[some_runtime_port_count];
ports = array_on_mains_stack;

Хитрость заключается в том, что, поскольку он находится в стеке, он действителен только из этой функции и любой функции, вызываемой ею. Как только вы вернетесь из этой функции, она, конечно же, будет освобождена.

person Ryan Graham    schedule 06.03.2009

ports и массив указателей на объекты port_t, поэтому, выполняя ports[0], вы получаете указатель, а не объект, и вам нужно получить к нему доступ с помощью ->

Возьмите хороший ресурс по указателям в C и прочитайте его от корки до корки. Есть также руководства по чтению объявлений C. Вы не сможете понять эту тему, получая ответы на случайные вопросы.

Вот ссылка, которую стоит прочитать.

person kyku    schedule 06.03.2009