-3
votes

Comment puis-je empêcher une fonction de libérer la mémoire d'une variable locale?

J'essaie d'enregistrer une variable locale à partir d'une fonction en stockant son adresse. Cependant, il semble que le compilateur libère automatiquement la mémoire de cette variable, même après que je stocke son adresse dans une variable de pointeur.

Je suis dans une situation (pas exactement comme le code ci-dessous) où je dois avoir le membre d'une classe Variable Stocker l'adresse d'une variable déclarée dans une fonction. xxx

idéalement, * p devrait être 5, mais cela finit par être un nombre qui N'EST PAS 5, et c'est une grande partie des moments où je répercute le script. Je crois que la mémoire allouée à A dans foo est libérée automatiquement. Comment puis-je vous assurer que * p est 5 malgré tout retard?


8 commentaires

Pourquoi pensez-vous que vous voulez faire cela?


Vous ne pouvez pas. Prenant l'adresse d'un local et de la désirer en dehors de la portée où il est défini est UB.


Voir Cette question .


À l'origine, cette question a été étiquetée avec C ( c ) et C ++ ( C ++ ). Ensuite, la balise C ++ a été supprimée, même si la question de la diversité des références est une non-concept dans un programme C. Les réponses, pas de manière déraisonnable, utilisent Nouveau et autres bits de C ++ ( unique_ptr , partagé_ptr , etc.). Il est probablement mieux étiqueté C ++ que c, donc - même si le code exemple est meilleur C code C ++.


Qu'est-ce que unique_ptr / partagé_ptr ?


@Alexb unique_ptr / Shared_PTR sont des pointeurs de gestion de la mémoire. Si vous connaissez des constructeurs avec destructeurs, ils suppriment automatiquement les données allouées lorsque la mémoire n'est plus utilisée. C'est un gros sujet, alors j'essaierais de regarder à travers des tutoriels pour voir si peut être quelque chose qui pourrait aider.


Préférez un livre hautement recommandé sur des tutoriels trouvés par les recherches sur le Web. Internet est jonché de mauvais tutoriels, d'autres que vous deviendrez un programmeur pire de les lire. Jusqu'à ce que vous sachiez assez bien la langue pour raconter de mauvais avis du mal, vous serez à la merci de Charlatans et de blâmer des abrutis. Si vous êtes toujours intéressé par des tutoriels, recherchez les experts de domaine reconnus et utilisez leurs didacticiels ou leurs tutoriels recommandés. Ne recommandez pas de tutoriels à moins que vous n'ayez un bon à l'esprit.


Duplicaillard possible de


4 Réponses :


0
votes

que est le point d'utilisation de variables de stockage automatiques, pour disparaître lorsqu'ils sortent de la portée. Les pointant après qu'ils soient détruits soit un comportement indéfini. UB peut vous rappeler une valeur correcte, une valeur incorrecte ou un crash de votre application, ou autre.

Si vous voulez le garder, ne le rendez pas local. Utilisez (et renvoyez) A unique_ptr / Shared_ptr (Bien que je ne vois pas pourquoi vous voulez faire cela dans votre code de toute façon).

Toutes les réponses suggérant une variable statique sont mauvaises. Bien que cela fonctionnera temporairement, il est tenu de créer beaucoup d'autres problèmes si vous en faites une habitude.


3 commentaires

J'ai essayé d'avoir la fonction renvoyer également A , mais laissez la variable retournée inutilisée. Cela corrigera-t-il le problème?


Pointeurs intelligents. Ils vont détruire automatiquement lorsqu'il n'est plus nécessaire. Ne faites jamais de nouveau / supprimer à nouveau.


@MichaelchourDakis Bien sûr, la liaison d'un pointeur global à une variable statique est mauvaise. Néanmoins, la question demande explicitement comment persister les données du pointeur après exécution de la fonction. Juste parce que la prémisse d'une question est «mauvaise» ne fait pas de réponses précises à cette question.




5
votes

Solution 1 - Allocation de mémoire dynamique avec de nouvelles et supprimées

Si vous souhaitez accéder à une mémoire accessible après une sortie de fonction, vous devez l'allouer de manière dynamique en utilisant nouveau p> p> xxx pré>

parce que ce pointeur a été attribué avec nouveau code>, il va rester jusqu'à ce que vous appelle Supprimer code> dessus: p>

int* p;
void foo() {
    static int a = 5;

    p = a;
}

int main() {
    foo(); 

    // stuff...

    std::cout << *p << '\n'; // Prints 5, unless you modified *p
}


2 commentaires

Et qu'est-ce que est viable et plus intelligent à votre avis?


@Alexb ne soyez pas trop intelligent. Vous ne pourrez pas le déboguer. Laissez le compilateur devenir intelligent, puis testez-le avec un profileur. S'il est trouvé vouloir, obtenez un peu plus intelligent avec les pires parties.



-1
votes

Utilisez une variable statique, et cela résoudra votre problème d'étant 5. La mémoire d'autre part ne sera pas enregistrée en raison du fait que c'est une variable locale.


0 commentaires

1
votes

Si vous souhaitez que la variable intérieure foo persiste après l'appel de la fonction, vous devez effectuer une variable une variable statique. C ++ est une machine à base de pile: cela signifie que la durée de vie d'une variable est limitée à sa portée. Dans votre exemple A est limité à la portée de foo . Si vous faites votre variable statique, il prolongera la durée de vie de votre variable à la portée de niveau supérieur, mais limitera votre accès à A dans votre fonction.

Je me sens comme ce que tu es Essayer de faire est très de code malodory, mais voici ce que vous avez demandé: xxx

dans cet exemple, vous êtes garantis que A sera initialisé sur votre premier appel et ne sera pas réutilisé ou supprimé jusqu'à la fin de votre programme.