web-dev-qa-db-fra.com

Quelle est la cause du membre de tableau flexible pas à la fin de l'erreur de structure?

Je me demande pourquoi je continue de recevoir error: flexible array member not at end of struct erreur lorsque j'appelle malloc. J'ai une structure avec un tableau de longueur variable et je reçois toujours cette erreur.

La structure est,

typedef struct {
  size_t N;
  double data[];
  int label[];
} s_col; 

et l'appel à malloc est,

col = malloc(sizeof(s_col) + lc * (sizeof(double) + sizeof(int)));

Est-ce le bon appel à malloc?

23
csta

Vous ne pouvez avoir qu'un seul membre de tableau flexible dans une structure, et il doit toujours être le dernier membre de la structure. En d'autres termes, dans ce cas, vous vous êtes trompé avant d'appeler malloc, au point qu'il n'y a vraiment aucun moyen d'appeler malloc correctement pour cette structure.

Pour faire ce que vous semblez vouloir (tableaux du même nombre de membres data et label), vous pouvez envisager quelque chose comme:

struct my_pair { 
    double data;
    int label;
};

typedef struct { 
   size_t N;
   struct my_pair data_label[];
};

Notez que ceci est quelque peu différent cependant: au lieu d'un tableau de doubles suivi d'un tableau de ints, il vous donne un tableau d'un double suivi d'un int, puis le double suivant, le int suivant, etc. Que cela soit suffisamment proche ou non dépendra de la façon dont vous utilisez les données (par exemple, pour passer à une fonction externe qui attend un tableau contigu, vous devrez probablement faire les choses différemment).

25
Jerry Coffin

Étant donné une définition de structure et un pointeur vers le début d'une structure, il est nécessaire que le compilateur C puisse accéder à n'importe quel membre de la structure sans avoir à accéder à autre chose. Étant donné que l'emplacement de chaque élément dans la structure est déterminé par le nombre et les types d'éléments qui le précèdent, l'accès à tout élément nécessite que le nombre et les types de tous les éléments précédents soient connus. Dans le cas particulier où le dernier élément est un tableau, cela ne pose aucune difficulté particulière, car l'accès à un élément dans un tableau nécessite de savoir où il commence (ce qui nécessite de connaître le nombre et le type des éléments précédents, plutôt que le nombre d'éléments dans le tableau lui-même) et l'index des éléments (que le compilateur peut supposer être plus petit que le nombre d'éléments pour lesquels l'espace existe, sans avoir à connaître quoi que ce soit sur la taille du tableau). Si un membre du tableau flexible apparaissait ailleurs qu'à la fin d'une structure, l'emplacement des éléments qui suivraient dépendrait du nombre d'éléments dans le tableau - ce que le compilateur ne saura pas.

5
supercat
typedef struct {
  size_t N;
  double data[];
  int label[];
} s_col; 

Vous ne pouvez pas avoir de membre de tableau flexible (double data[]) au milieu. Considérez la taille du tableau codé en dur ou double *data

3
J-16 SDiZ