Si seulement en utilisant le premier élément, est-ce que je dois allouer mem pour toute la structure?

J’ai une structure dans laquelle le premier élément est testé et, en fonction de sa valeur, le rest de la structure sera lu ou non. Dans les cas où la valeur du premier élément indique que le rest de la structure ne sera pas lu, dois-je allouer suffisamment de mémoire pour la structure entière ou uniquement pour le premier élément?

struct element { int x; int y; }; int foo(struct element* e) { if(e->x > 3) return e->y; return e->x; } 

en principal:

 int i = 0; int z = foo((struct element*)&i); 

Je suppose que si seule l’allocation pour le premier élément est valide, je devrais me méfier de tout ce qui pourrait tenter de copier la structure. c’est-à-dire passer la structure à une fonction.

ne forcez pas vos informations dans des structures non nécessaires: n’utilisez pas la structure comme paramètre de votre fonction.

soit passez le membre de votre structure à la fonction, soit utilisez l’inheritance:

 typedef struct { int foo; } BaseA; typedef struct { int bar; } BaseB; typedef struct { BaseA a; BaseB b; } Derived; void foo(BaseB* info) { ... } ... Derived d; foo(&d.b); BaseB b; foo(&b); 

si vous êtes simplement curieux (et ne l’utilisez pas sérieusement): vous pouvez.

 typedef struct { int foo, goo, hoo, joo; } A; typedef struct { int unused, goo; } B; int foo(A* a) { return a->goo; } ... B b; int goo = foo((A*)&b); 

En général, vous devez allouer à un bloc de mémoire au moins autant d’octets que nécessaire pour lire intégralement le membre auquel le décalage est le plus grand dans votre structure. De plus, lorsque vous écrivez dans ce bloc, vous devez vous assurer d’utiliser les mêmes décalages de membres que dans la structure d’origine.

En réalité, une structure n’est qu’un bloc de mémoire avec différentes zones auxquelles sont atsortingbuées différentes interprétations (int, char, autres structures, etc.) et pour accéder à un membre d’une structure (après réorganisation et alignement), il s’agit simplement de lire ou de écrire dans un peu de mémoire.

Je ne pense pas que le code en tant que donné est légitime. Pour comprendre pourquoi, considérons:

 struct CHAR_AND_INT { unsigned char c; int i; } CHAR_AND_INT *p; 

Un compilateur serait en droit de supposer que p->c sera aligné sur les mots et aura tout le remplissage nécessaire pour que p->i soit également aligné sur les mots. Sur certains processeurs, l’écriture d’un octet peut être plus lente que l’écriture d’un mot. Par exemple, une instruction de stockage d’octets peut demander au processeur de lire un mot dans la mémoire, de mettre à jour un octet et de réécrire le tout, alors qu’une instruction de stockage de mots pourrait simplement stocker les nouvelles données sans rien lire au préalable. . Un compilateur sachant que p->c serait aligné sur les mots et complété pourrait implémenter p->c = 12; en utilisant un magasin de mots pour écrire la valeur 12. Un tel comportement ne produirait pas les résultats souhaités, cependant, si l’octet suivant p->c ne remplissait pas, mais contenait plutôt des données utiles.

Bien que je ne m’attende pas à ce qu’un compilateur impose des exigences “spéciales” d’alignement ou de remplissage à une partie de la structure indiquée dans la question initiale (au-delà de celles qui s’appliquent à int ), je ne pense pas que quoi que ce soit dans la norme empêcherait un compilateur de le faire alors.

Vous devez seulement vérifier que la structure elle-même est allouée. pas les membres (du moins dans ce cas)

 int foo(struct element* e) { if ( e != 0) // check that the e pointer is valid { if(e->x != 0) // here you only check to see if x is different than zero (values, not pointers) return e->y; } return 0; } 

Dans votre édition modifiée, je pense que c’est un mauvais codage

int i = 0; int z = toto ((élément struct *) & i);

Dans ce cas, je vais être alloué sur la stack, donc son adresse est valide; et sera valable dans foo; mais puisque vous le transformez en quelque chose de différent, les membres seront au mieux (ordures) Pourquoi voulez-vous transtyper un int dans une structure? Quelle est votre intention?