1
votes

Portée C ++ sur le tas

Pourquoi j'obtiens une sortie sous la forme 10 après avoir supprimé sa portée? J'ai créé une classe A qui a une variable membre de type pointeur et une autre classe B qui a une autre variable membre x . J'alloue maintenant de la mémoire sur le tas pour B avec la valeur 10 pour x . Pour créer une instance de la classe A , j'ai utilisé l'adresse mémoire de x . Je supprime maintenant l'objet b et j'imprime la valeur du pointeur ref de la classe A . Je comprends pourquoi j'obtiens une sortie au format 10 , car nous pouvons voir que la mémoire contenant cette valeur ne persiste plus sur le tas?

#include<iostream>
using namespace std;

class A
{    
   public:
   int *ref;
   A(int *ref):ref(ref)
   {
   }
};

class B{
   public:
   int x;
   B(int x):x(x){}
};

int main()
{
   B *b=new B(10);
   A a(&b->x);
   delete b;
   cout<<*a.ref<<endl; 
}


2 commentaires

Presque toutes les opérations de suppression sur PC ne permettent pas d'effacer les ressources, mais libèrent simplement l'espace qu'elles occupaient pour une utilisation future. Ainsi, les données peuvent encore exister pendant un certain temps, mais le résultat de l'accès à ces données n'est pas défini.


Hors sujet, mais vous utilisez le terme champ d'application de la mauvaise manière. La portée fait référence à la partie du code source où un nom est visible. Il ne fait pas référence à la durée de vie d'une variable, qui est généralement appelée étendue. Ainsi, les données allouées sur le tas ont une étendue indéfinie (car elles vivent jusqu'à ce que vous les supprimiez) mais toutes les variables de pointeur pointant sur ces données ont les règles de portée normales.


3 Réponses :


4
votes

C'est un comportement indéfini. Par exemple, lorsque j'exécute votre exemple dans MSVC, ma sortie est -572662307 .

Il n'y a aucune garantie sur ce qui se passe si vous essayez d'accéder à une mémoire non valide. Ce qui arrivera probablement, c'est qu'il accède de toute façon à la mémoire invalide, et si cette mémoire n'a pas changé, vous pouvez obtenir l'ancienne valeur. C'est en fait une mauvaise chose, car il semble que le programme fonctionne comme prévu, alors qu'en réalité ce n'est pas le cas.

Je comprends pourquoi j'obtiens une sortie aussi 10 que nous pouvons voir cette mémoire conserver cette valeur ne persiste plus sur le tas?

La mémoire n'est plus valide, mais le nombre 10 peut toujours être dans cette mémoire, et a.ref pointe toujours vers cette mémoire. Donc, même si la mémoire n'est pas valide, le 10 peut toujours persister.


0 commentaires

0
votes

Ce que vous avez, c'est un comportement indéfini car le programme accède à une mémoire qui ne lui appartient plus.
delete libère la mémoire afin qu'elle puisse être réutilisée, mais cela ne signifie pas que la valeur de cet emplacement mémoire est mise à zéro (si c'est ce que vous attendiez).


0 commentaires

0
votes

C'est à cause de l'effet de pointeur suspendu. Bien que nous ayons supprimé, les données de la mémoire ne sont pas encore effacées ou aucune autre donnée n'est stockée là-bas et notre pointeur pointe toujours vers cette mémoire.

pour référence https://www.geeksforgeeks.org/dangling-void-null-wild -pointeurs /


0 commentaires