Comment inclure un tableau dynamique à l'INTÉRIEUR d'une struct en C?
J'ai regardé autour, mais ont été incapables de trouver une solution à ce qui doit être un bien posé la question.
Voici le code que j'ai:
#include <stdlib.h>
struct my_struct {
int n;
char s[]
};
int main()
{
struct my_struct ms;
ms.s = malloc(sizeof(char*)*50);
}
et voici l'erreur de gcc me donne:
erreur: invalid use of flexible membre du groupe
Je peux le faire pour compiler si je déclare la déclaration de s à l'intérieur de la structure pour être
char* s
ce qui est probablement supérieure de mise en œuvre (de l'arithmétique des pointeurs est plus rapide que les tableaux, oui?)
mais je pensais que c une déclaration de
char s[]
est le même que
char* s
char s[]
est le même quechar *s
seulement à l'intérieur d'une fonction de la liste des paramètres.
Vous devez vous connecter pour publier un commentaire.
La façon dont vous l'avez écrit maintenant , l'habitude d'être appelé le "struct hack", jusqu'à ce que le C99 béni comme un "flexible membre du groupe". La raison pour laquelle vous obtenez une erreur (sans doute de toute façon), c'est qu'il doit être suivi par un point-virgule:
Lorsque vous allouer de l'espace pour cela, vous souhaitez allouer la taille de la structure plus la quantité d'espace que vous souhaitez pour le tableau:
Dans ce cas, le flexible de membre de tableau est un tableau de char, et sizeof(char)==1, de sorte que vous n'avez pas besoin de multiplier par sa taille, mais comme toute autre malloc vous auriez besoin de si c'était un tableau d'un autre type:
Edit: Cela donne un résultat différent de changer le membre à un pointeur. Dans ce cas, vous avez (normalement) besoin de deux allocations séparés, l'un pour la structure elle-même, et l'autre pour les "extra" les données à être pointé par le pointeur. L'utilisation d'un flexible de membre du groupe que vous pouvez allouer toutes les données en un seul bloc.
Vous devez décider ce que vous essayez de faire tout d'abord.
Si vous voulez avoir une structure avec un pointeur vers un [indépendant] tableau à l'intérieur, vous devez le déclarer comme
Dans ce cas, vous pouvez créer la structure de l'objet en aucune façon que vous s'il vous plaît (comme une variable automatique, par exemple)
et ensuite d'allouer de la mémoire pour le tableau de façon indépendante
En fait, il n'y a pas lieu d'allouer le tableau de la mémoire dynamiquement
Tout dépend de quel genre de vie vous avez besoin de ces objets. Si votre structure est automatique, puis dans la plupart des cas, le tableau serait également automatique. Si la structure de l'objet possède la matrice de mémoire, il n'y a pas de raison de faire autrement. Si la structure elle-même est dynamique, alors la matrice devrait normalement être dynamique.
Noter que dans ce cas, vous avez deux indépendants des blocs de mémoire: la structure et le tableau.
Une approche complètement différente consisterait à utiliser la "struct hack" l'idiome. Dans ce cas, le tableau devient une partie intégrante de la structure. Résident tous les deux dans un seul bloc de mémoire. En C99 la structure devrait être déclaré comme
et de créer un objet que vous auriez à allouer toute la chose de façon dynamique
La taille du bloc de mémoire dans ce cas, est calculé de façon à accueillir les les membres de la structure et le second tableau de la durée d'exécution de taille.
Noter que dans ce cas, vous n'avez pas l'option pour créer une telle structure d'objets statiques ou automatique des objets. Des structures souples, les membres du groupe à la fin ne peut être attribuée de façon dynamique dans la C.
Votre hypothèse sur pointeur aritmetics être plus rapide, puis les tableaux, est absolument incorrect. Tableaux par le biais de l'arithmétique de pointeur, par définition, de sorte qu'ils sont fondamentalement les mêmes. En outre, un véritable tableau (pas pourri pour un pointeur) est généralement un peu plus rapide qu'un pointeur sur un objet. La valeur du pointeur doit être lu à partir de la mémoire, tandis que le tableau de l'emplacement dans la mémoire est "connu" (ou "calculer") à partir de la matrice de l'objet lui-même.
L'utilisation d'un tableau de taille quelconque est autorisé uniquement à la fin d'une structure, et ne fonctionne que dans certains compilateurs. C'est un non-standard compilateur extension. (Bien que je pense que je me souviens C++0x sera qui le permettent.)
Le tableau ne sera pas une allocation distincte de la structure si. Si vous avez besoin d'allouer la totalité de la
my_struct
, non seulement le tableau de la partie.Ce que j'ai à faire est de simplement donner le tableau, mais une petite taille non nulle. Généralement 4 pour des tableaux de caractères et de 2 pour
wchar_t
tableaux de préserver 32 bits d'alignement.Alors vous pouvez prendre l'déclaré la taille de la matrice en compte, lorsque vous effectuez l'affectation. J'ai souvent ce n'est pas sur la théorie que de la pâtée est plus petite que la granularité que le gestionnaire de tas fonctionne dans tous les cas.
Aussi, je pense que vous ne devriez pas utiliser sizeof(char*) dans votre allocation.
C'est ce que je ferais.
Tableaux résoudre à des pointeurs, et ici vous doit définir
s
commechar *s
. La structure est fondamentalement un conteneur, et doit (IIRC) fixe la taille, afin d'avoir dynamiquement un tableau de taille à l'intérieur d'elle n'est tout simplement pas possible. Puisque vous êtesmalloc
ing la mémoire de toute façon, cela ne devrait pas faire de différence dans ce que vous êtes après.En fait, vous dites,
s
indiquera l'emplacement de la mémoire. Notez que vous pouvez toujours y accéder ultérieurement à l'aide de la notation commes[0]
.Pas du tout - ils sont en fait la même. les tableaux de traduire à l'arithmétique de pointeur au moment de la compilation.
Je soupçonne que le compilateur ne sait pas de combien d'espace il sera nécessaire d'allouer pour s[], si vous choisissez de déclarer une variable automatique avec elle.
Je suis d'accord avec ce que dit Ben, déclarer votre struct
Aussi, afin de clarifier son commentaire sur le stockage, déclarant
char *s
de ne pas mettre la structure de la pile (puisque c'est allouée dynamiquement) et allouers
dans le tas, ce qu'il va faire, c'est interpréter le premiersizeof(char *)
octets de votre tableau comme un pointeur, donc vous ne serez pas en exploitation sur les données vous pensez que vous êtes, et sera probablement fatale.Il est essentiel de se rappeler que, même si les opérations sur les pointeurs et les tableaux peuvent être appliquées de la même manière, ils ne sont pas la même chose.
le code généré sera identique (tableau et ptr). Outre le fait que le tableau habitude de compiler c'est
et BTW - faire de c++ et de l'utilisation du vecteur