Votre intution sur "pourquoi ne pas utiliser un tableau de taille 1" est sur place.
Le code est en train de faire le "C struct hack" de mal, parce que les déclarations de longueur zéro tableaux sont une violation de contrainte. Cela signifie qu'un compilateur peut rejeter votre hack droit au large de la chauve-souris au moment de la compilation avec un message de diagnostic qui s'arrête à la traduction.
Si nous voulons à commettre un hack, nous devons nous faufiler passé le compilateur.
La bonne façon de faire de la "C struct hack" (qui est compatible avec le C dialectes datant de 1989 en C ANSI, et probablement beaucoup plus tôt) est d'utiliser un bon tableau de taille 1:
struct someData
{
int nData;
unsigned char byData[1];
}
En outre, au lieu de sizeof struct someData
, la taille de la partie avant de l' byData
est calculé à l'aide de:
offsetof(struct someData, byData);
Pour allouer un struct someData
avec de l'espace pour 42 octets en byData
, nous aurions alors utiliser:
struct someData *psd = (struct someData *) malloc(offsetof(struct someData, byData) + 42);
Notez que ce offsetof
calcul est en fait le bon calcul, même dans le cas de la taille de la matrice étant zéro. Vous voyez, sizeof
de l'ensemble de la structure peut inclure rembourrage. Par exemple, si nous avons quelque chose comme ceci:
struct hack {
unsigned long ul;
char c;
char foo[0]; /* assuming our compiler accepts this nonsense */
};
La taille de l' struct hack
est très probablement rembourré pour l'alignement en raison de l' ul
membre. Si unsigned long
est de quatre octets de large, puis, éventuellement, sizeof (struct hack)
8, alors que offsetof(struct hack, foo)
est presque certainement 5. L' offsetof
méthode est le moyen d'obtenir la taille exacte de la partie précédente de la structure, juste avant le tableau.
Alors que ce serait le moyen de refactoriser le code: le rendre conforme à la classique, ultra-portable struct hack.
Pourquoi ne pas utiliser un pointeur? Car un pointeur occupe de l'espace supplémentaire et doit être initialisé.
Il y a d'autres bonnes raisons de ne pas utiliser un pointeur, à savoir qu'un pointeur nécessite un espace d'adressage pour être utile. La structure hack est externalizeable: c'est-à-dire, il existe des situations dans lesquelles une telle disposition est conforme à la de stockage externes tels que les zones de fichiers, les paquets ou de la mémoire partagée, dans laquelle vous ne voulez pas des pointeurs, car ils ne sont pas significatives.
Il y a plusieurs années, j'ai utilisé la structure hack dans une mémoire partagée message passing interface entre le noyau et l'espace utilisateur. Je ne voulais pas les pointeurs, parce qu'ils auraient été significative seulement l'espace d'adressage du processus de génération d'un message. Le noyau d'une partie du logiciel a une vue à la mémoire à l'aide de sa propre cartographie à une adresse différente, et donc, tout était basé sur des calculs de décalage.