0
votes

Initialisation du pointeur de structure contenant un pointeur de structure du même type

J'essaie de comprendre comment l'initialisation d'un pointeur à un objet de structure (qui contient un pointeur sur une structure du même type) se produit. E.g j'ai un struct : xxx

suppose que j'ai l'adresse de départ d'un pool de mémoire I.e piscine est un pointeur à l'emplacement de départ. (Pour des arguments, disons que la mémoire de départ est 1001 .) xxx

maintenant je déclare un pointeur de type noeud > et attribuez-lui la mémoire de départ via reterpret_cast . xxx

actuellement a pointe vers la mémoire 1001 < / code>. Maintenant, je déclare un autre pointeur xxx

maintenant ce qui se passe est que b pointe vers la même adresse que a ie 1001 . Le pointeur B-> Suivant pointe vers un emplacement aléatoire attendu, mais l'adresse du pointeur b-> suivant est identique à l'adresse à laquelle b est pointant IE 1001 . Ie xxx

Je ne comprends pas pourquoi l'adresse du b-> suivant est identique à celle de laquelle le pointeur b < / code> est pointé? Selon ma compréhension B-> Suivant doit être localisée où B est situé.

ps: j'ai essayé de trouver comment cela se produit mais ne pouvait pas trouver la documentation correspondante. Si ce type de question est déjà répondu dans une documentation ou une autre question, veuillez fournir un lien.

PPS: Après avoir discuté de ce problème avec ma collègue, j'ai découvert que B est un pointeur et non un objet. Il pointe vers un emplacement (c.-à-d. 1001 ) où selon B un objet de nœud existe qui contient le pointeur suivant et donc l'adresse de < Code> B-> Suivant ( & B-> Suivant ) est identique à celui de l'emplacement sur lequel B pointe.

< img src = "https://i.stack.imgur.com/vtgnr.png" alt = "Entrez la description de l'image ici">


5 commentaires

noeud * A = 1001; ne compilera pas.


Puisque vous avez utilisé la balise C ++ 17 spécifiquement, j'ai supprimé la balise C. C et C ++ sont des langues différentes et la réponse peut dépendre de cela. Si vous souhaitez poser des questions sur C, veuillez modifier les balises C ++ à une balise C.


Pourquoi l'adresse de B-> Suivant est-elle différente de celle à laquelle b pointe-t-il? Où autre serait B-> Suivant être situé, à votre avis? Le fait que les deux sont de type nœud * n'est pas pertinent. Envisager: struct s {int n;}; S s; STD :: COUT << ((VOID *) & S == (VOID *) & S.N); Ceci imprimera 1


Essayer des choses aléatoires n'est pas un bon moyen d'apprendre C ++.


Le pointeur est dur et un long sujet. Je suggère de passer à travers le (s) Cahpter (s) d'un Good C ++ Book sur les pointeurs et ensuite voir si cela répond à votre question. Un autre bit d'informations nécessaire est que pour les types de mise en page standard (quel nœud est), l'adresse de la classe est la même que l'adresse du premier membre.


3 Réponses :


-1
votes

C'est une exigence de C ++ (rembourrage de la mémoire modulo): le premier membre d'une structure est situé à la même adresse que la structure elle-même.

pour la comparaison, Vous pouvez le voir comme une matrice, dans la chaîne

abcd

(le A est pris à des fins pratiques, ce n'est pas le même que le a dans votre question)

Le A est situé au même emplacement que la chaîne abcd . La chaîne est votre structure et chaque lettre est un champ. A peut être nœud :: Suivant . Le terme "pointant vers une structure" est un synonyme de "pointant vers le premier octet de la structure donnée".

Par exemple, si la question est, où est la chaîne abcd dans cette séquence:

1234ABCD56789

Vous diriez que 4 parce que c'est où le premier élément de la chaîne est. C'est juste la même chose, dans la plupart des cas, avec C ++. Et A est également situé dans la position 4 .

Remarque: Comme mentionné par Nathanolivier, ceci n'est valable que pour Types de mise en page standard .


1 commentaires

Le premier membre d'une structure pointe dans la même adresse que la structure elle-même. Ceci n'est garanti que pour les types de mise en page standard.



1
votes

permet de dire que je déclare un pointeur de type nœud et attribuez-lui une mémoire de départ (E.G 1001)

Pour l'argument, je vais prétendre que ce code compile, que vous pouvez attribuer directement un entier arbitraire à un pointeur sans REINIERPRET_CAST . .

A est maintenant ce que c ++ appelle un "pointeur non valide". C'est un pointeur, mais cela ne souligne rien.

Que se passe-t-il est que "B" pointe vers la même adresse que "A" I.E 1001.

c'est correct. B est maintenant aussi invalide que A .

Le pointeur "B-> Suivant"

Nope. Si vous déroute un pointeur invalide, vous obtenez un comportement indéfini. B ne pointe pas réellement un objet noeud , il n'y a donc aucun B-> Suivant Pointeur. Donc, parler de la valeur d'un B-> Suivant Pointeur qui n'existe pas n'a pas de sens.

L'adresse du pointeur "B-> Suivant" est identique à celle de laquelle B est dirigé I.e 1001.

Cela ressemble à ce que vous parlez réellement est la mise en page du noeud de struct . Le fait que, étant donné un objet de type nœud , l'adresse de cet objet et l'adresse de son premier membre de données sera la même. Puisque nœud est la mise en page standard, qui sera vraie.

Mais il est important de noter que l'adresse du premier membre de données n'est pas l'adresse que suivant points sur . C'est l'adresse de suivant elle-même . Un objet pointeur un objet, tout comme n'importe quel autre objet, il a donc un stockage en mémoire. Par conséquent, vous pouvez obtenir un pointeur à un pointeur . C'est ce pointeur sur le pointeur suivant qui aura la même adresse que le nœud objet il vit dans, pas la valeur du Suivant Pointeur lui-même.

C'est-à-dire, dans un exemple hypothétiquement valide, l'adresse de B et & b-> suivante serait la même.


0 commentaires

2
votes

permet de prendre les locaux de base, mais avec un exemple valide à la place:

+---+
| a | --\
+---+    \     +-----------------+
          >--> | the node object |
+---+    /     +-----------------+
| b | --/
+---+


2 commentaires

C'est rationnel: Si A = B, F (A) = F (B).


"pourrait différer" -> "pourrait sembler différer"