Динамическое выделение памяти для массива структур в c

У меня есть две структуры, как показано ниже

struct server{
    // some members
};

struct msg{
    struct server* servers;
};

Тогда я делаю это.

struct msg msg1;
struct server s1,s2;

msg1.servers = (struct server *)malloc(2*sizeof(struct server));
msg1.servers[0] = &s1; // compilation error 
msg1.servers[1] = &s2;  // compilation error

Этот код не компилируется и выдает следующую ошибку: несовместимые типы при назначении типа «структурный сервер» из типа «структурный сервер *».

Что я делаю не так?


person FourOfAKind    schedule 19.04.2012    source источник


Ответы (5)


Проблема здесь в том, что выражение msg1.servers[0] производит struct server, но вы предоставляете struct server* (тип указателя против типа без указателя). Есть два способа это исправить

Во-первых, просто предоставить экземпляры struct server по значению, как ожидает код.

msg1.servers[0] = s1;
msg1.servers[1] = s2;

Это будет работать, если struct server — это тип, который ведет себя правильно при копировании.

Второй необходим, если вы хотите продолжать использовать struct server* в struct msg. В этом случае вам нужен двойной указатель для хранения указателей сервера. И вам нужно соответствующим образом скорректировать свое утверждение malloc

struct msg{
    struct server** servers;
};

msg1.servers = malloc(2*sizeof(struct server*));
msg1.servers[0] = &s1; 
msg1.servers[1] = &s2;
person JaredPar    schedule 19.04.2012

Амперсанды не нужны:

msg1.servers[0] = s1;
msg1.servers[1] = s2;

Сказав &s1, вы получите указатель на struct server, но msg1.servers[0] — это единственный элемент в массиве, который вы только что выделили.

person Dave    schedule 19.04.2012

msg.servers — это указатель на тип server. Когда вы используете msg.servers[0], вы разыменовываете указатель, поэтому его тип теперь server, а не server *, очевидно, вы не можете присвоить ему адрес экземпляра server.

Вы, вероятно, хотите следующее:

struct msg{
  struct server** servers;
};

struct msg msg1;
struct server s1,s2;

msg1.servers = malloc(2 * sizeof(struct server *));
msg1.servers[0] = &s1;
msg1.servers[1] = &s2;
person Praetorian    schedule 19.04.2012

msg1.servers[0] = &s1;

Нижний индекс массива неявно разыменовывает указатель (a[i] == *(a + i), поэтому тип выражения msg1.servers[0] равен struct server, а не struct server *.

Измените определение struct msg на

struct msg {
  struct server **servers; // servers will be an array of pointers
};

и malloc вызов

msg1.servers = malloc(2 * sizeof *msg1.servers); 

и тогда задания будут работать.

ИЗМЕНИТЬ

Или, как все остальные указывают, уберите & из задания. Это зависит от того, что вы собираетесь servers представлять; это массив struct server или массив указателей на struct server?

person John Bode    schedule 19.04.2012

Вам нужен массив указателей

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

int main(void)
{
    struct server{
        // some members
    };  

    struct msg{
        struct server ** servers;
    };  

    struct msg msg1;
    struct server s1,s2;

    if ((msg1.servers = malloc(2 * sizeof(struct server *))) == NULL) {
        printf("unable to allocate memory \n");
        return -1; 
    }   
    msg1.servers[0] = &s1; // compilation error 
    msg1.servers[1] = &s2;  // compilation error

    free(msg1.servers);

    return 0;
}
person Sangeeth Saravanaraj    schedule 19.04.2012