Wat is de oorzaak van een flexibel array-lid dat niet aan het einde van de structuurfout staat?

Ik vraag me af waarom ik steeds de error: flexible array member not at end of struct-fout krijg wanneer ik malloc aanroep. Ik heb een struct met een array van variabele lengte en ik krijg steeds deze foutmelding.

De structuur is,

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

en de oproep aan malloc is,

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

Is dit de juiste oproep aan malloc?


Antwoord 1, autoriteit 100%

Je kunt maar één flexibel arraylid in een struct hebben en dit moet altijd het laatste lid van de struct zijn. Met andere woorden, in dit geval heb je de fout gemaakt voordat je mallocaanroept, tot het punt dat er echt geen manier is om malloccorrect aan te roepen voor deze struct.

Om te doen wat je lijkt te willen (arrays van hetzelfde aantal dataen labelleden), kun je iets overwegen als:

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

Merk op dat dit echter enigszins anders is: in plaats van een array van doubles gevolgd door een array van ints, krijg je een array van één doublegevolgd door één int, dan de volgende double, volgende int, enzovoort. Of dit in de buurt komt van hetzelfde of niet, hangt af van hoe u de gegevens gebruikt (bijvoorbeeld om door te geven aan een externe functie die een aaneengesloten array verwacht, moet u dingen waarschijnlijk anders doen).


Antwoord 2, autoriteit 33%

Gegeven een struct-definitie en een verwijzing naar het begin van een struct, is het noodzakelijk dat de C-compiler toegang heeft tot elk lid van de struct zonder toegang tot iets anders. Aangezien de locatie van elk item binnen de structuur wordt bepaald door het aantal en de soorten items die eraan voorafgaan, vereist toegang tot een item dat het aantal en de soorten van alle voorgaande items bekend zijn. In het specifieke geval waarin het laatste item een array is, levert dit geen bijzondere problemen op, aangezien toegang tot een item in een array vereist dat u weet waar het begint (waarvoor u het aantal en het type van voorafgaandeitems moet kennen, in plaats van het aantal items in de array zelf), en de itemindex (waarvan de compiler mag aannemen dat deze kleiner is dan het aantal items waarvoor ruimte is, zonder iets te hoeven weten over de grootte van de array). Als een Flexible Array Member echter ergens anders zou verschijnen dan aan het einde van een struct, zou de locatie van alle items die erop volgden afhangen van het aantal items in de array – iets wat de compiler niet zal weten.


Antwoord 3, autoriteit 13%

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

Dat kan niet
flexibel arraylid (double data[]) in het midden. Overweeg hardgecodeerde arraygrootte of double *data

Other episodes