2
votes

Tableau de structure alloué dynamiquement avec un élément de tableau de structure alloué dynamiquement

Veuillez considérer le code suivant:

y[i].x = new X[M];

Maintenant, j'alloue de la mémoire dynamiquement comme suit:

struct Y *y = new Y[N];

Et pour chaque élément de ce structure, j'alloue également de la mémoire pour y [i] .x comme suit-

struct X
{
   int x1;
   int x2;
};

struct Y
{
   int y1;
   struct X *x;
};

Dans ce cas, comment le système allouera mémoire pour y avant de connaître la taille réelle de la mémoire de y[i .x.

Je reçois une erreur de segmentation dans ce cas. Existe-t-il un bon moyen d'allouer dynamiquement de la mémoire? Que faire si j'ai besoin de réallouer de la mémoire (pour augmenter dynamiquement la taille du tableau)?


6 commentaires

Il allouera de la mémoire pour un pointeur. Ce pointeur ne sera cependant pas initialisé. Vous devriez arrêter d'utiliser de nouveau tous ensemble.


la taille de x est toujours la même, c'est un pointeur


Vous souhaitez utiliser std :: vector .


Chaque fois que vous pensez "tableau dynamique", votre prochaine pensée devrait presque toujours être std :: vector .


@someprogrammerdude les humains sont comme des vecteurs. Nous nous développons parfois mais la réduction est difficile.


vector n'est pas seulement un tableau dynamique sophistiqué. Notez que votre struct Y est cassé de plusieurs manières. Il peut être copié, mais de mauvaises choses se produisent si vous le faites. Il peut être utilisé avec le stockage automatique, mais lorsqu'il sort de sa portée, il perd de la mémoire. Il en faut beaucoup plus pour obtenir de bonnes allocations de mémoire dynamique, quelque chose que vous ne voulez pas réécrire à chaque fois, car quelqu'un d'autre l'a déjà fait pour vous: std :: vector


4 Réponses :


0
votes

Dans ce cas, comment le système allouera-t-il de la mémoire pour y avant de connaître la taille réelle de la mémoire de y [i] .x

En Y le type de x est un pointeur sur X , donc la taille est la taille d'un pointeur, la taille du le bloc mémoire pointé n'est pas pertinent lors de l'allocation de Y

Existe-t-il un bon moyen d'allouer dynamiquement de la mémoire? Que faire si j'ai besoin de réallouer de la mémoire (pour augmenter dynamiquement la taille du tableau)?

Visiblement, vous avez besoin d'un std::vector plutôt que d'un pointeur vers X, vous êtes en C ++, pas en C


7 commentaires

vous n'avez pas besoin de mentionner C. C ++ n'est pas un meilleur C. C est un langage différent pour différents problèmes avec des solutions différentes


@ user463035818 Je n'ai jamais dit que C ++ était meilleur que C, où lisez-vous cela? Je dis juste que l'OP utilise une manière similaire à ce que nous faisons en C, et qu'il est plus pratique d'utiliser vecteur existant en C ++ mais n'existant pas en C. Vous interprétez mal ma phrase ;-)


Je ne vous ai pas cité littéralement, mais le fait que C n'ait pas de vecteur n'est pas pertinent, le seul message qu'il véhicule est que C ++ serait meilleur parce qu'il a un vecteur. Oui, c'est comme ça que je pense que votre phrase peut être interprétée. Btw aucune raison de se sentir offensé, j'ai juste pensé que ce serait bien de vous dire pourquoi je n'ai pas voté pour;)


@ user463035818 "C n'a pas de vecteur n'est pas pertinent": encore une fois vous interprétez mal, je n'ai jamais dit "C n'a pas de vecteur", j'ai dit "C ++ a un vecteur". Si étrange ...


vous pouvez insister sur le fait que mon interprétation est erronée, ou vous pouvez considérer mon point de vue. Pas vraiment étrange, mais un peu triste ...


@ user463035818 vous faites une remarque sur ma réponse, je ne vous demande jamais de le faire, je viens de réagir à vos remarques. Depuis le début, vous considérez visiblement que je compare C et C ++ et que vous dites "C ++ est meilleur" ou C "n'a pas", non, je dis profiter des fonctionnalités C ++. Vous me demandez de réfléchir à votre point de vue mais vous ne considérez pas le mien ;-) Il y a une sorte de quiproquo, qui peut être long ... ^^


cela ne mène nulle part. Juste un dernier commentaire: je n'ai jamais prétendu que vous dites "C ++ est meilleur". Je viens de faire un argument exagéré pour faire passer mon message, je suis désolé d'avoir déclenché une discussion inutile en faisant cela;)



3
votes

Dans ce cas, comment le système allouera-t-il la mémoire pour y avant de connaître la taille réelle de la mémoire de y [i] .x .

La compilation connaît la taille d'un pointeur, car x est actuellement déclaré.
L'erreur de segmentation se produit très probablement lorsque vous essayez de déréférencer y [i] .x car vous n'avez jamais correctement alloué la mémoire vers laquelle il doit pointer.

Existe-t-il un bon moyen d'allouer dynamiquement de la mémoire?

Oui, il y en a. Vous devez utiliser std :: vector strong > pour le laisser gérer tous les obstacles et pièges en faisant la gestion manuelle de la mémoire pour vous:

struct X
{
   int x1;
   int x2;
};

struct Y
{
   int y1;
   std::vector<X> x;
};

std::vector<Y> y(N);
y[i].x.resize(M);

Que faire si j'ai besoin de réallouer de la mémoire (pour augmenter dynamiquement la taille du tableau)?

Cela sera également géré par la classe std :: vector .


0 commentaires

4
votes

Dans ce cas, comment le système allouera-t-il la mémoire pour y avant de connaître la taille réelle de la mémoire de y [i] .x .

Oh, mais il connaît la taille de y [i] .x . Le type de ce membre est struct X * qui est un pointeur. La taille d'un pointeur varie selon les architectures, mais elle est généralement de 32 sur 64 bits. Indépendamment de ce qu'est X (il y a peu de cas extrêmes comme les pointeurs de fonction).

En d'autres termes, X n'est pas un morceau de Y . En fait, Y a un pointeur qui pointe vers un morceau de mémoire occupé par (éventuellement plusieurs) X .

C'est comme avoir une adresse. Vous pouvez l'écrire sur un petit morceau de papier et le conserver. Tout le monde connaît la taille du papier. Indépendamment du nombre (et de la taille) de maisons occupant la place réelle.

Votre erreur de segmentation n'a rien à voir avec tout cela. Vous avez probablement franchi une limite. Mais c'est difficile à dire sans le code réel.


0 commentaires

2
votes

y [i] .x est toujours un pointeur qui a une taille fixe sur chaque système. (Il s'agit principalement de 32/64 bits). C'est pourquoi le système sait combien de mémoire allouer pour chaque instance de Y.


0 commentaires