11
votes

Utilise des références au lieu des pointeurs, résolvez des fuites de mémoire en C ++?

La plupart des fuites de mémoire apparaissent lorsqu'un pointeur d'un objet renvoyé et un programmateur a oublié de la supprimer.

Par exemple: p>

class my_class
{
  ...
};

my_class& func()
{
  my_class* c = new my_class;
  return *c;
}

int main()
{
  my_class& var1 = func();

  // I think there is no memory leak.
}


5 commentaires

Recherchez-vous à Boost Smart Pointers pour une autre couche de fuite de mémoire Solving Goodness.


Il n'y a rien à oublier Sauf peut-être que vous avez peut-être attribué la mémoire que vous n'avez pas publiée et que vous avez donc une fuite de mémoire. Oh, et pourrait également oublier quelles fonctions renvoient des références à des objets que vous devez Supprimer après et quelle fonction renvoie des références à des objets gérés ailleurs ...


Je ne suis toujours pas entièrement convaincu que my_class * c = nouveau my_class; retour * c; ne provoque pas de fuite de mémoire. Bien sûr, le destructor peut être appelé lorsque (dans ce cas) var2 est hors de portée, mais la mémoire ne sera probablement pas publiée.


@Chris: Comme le type de fonction de retour est des références, il n'y a pas de fuite de mémoire.


Amir: Découvrez la réponse de @benjamin Lindley.


5 Réponses :


3
votes

Ne retourne pas les pointeurs bruts des fonctions; Collez-les dans une classe de pointeur intelligente telle que unique_ptr ou partagé_ptr . Ensuite, vous n'avez pas à vous soucier de supprimer l'objet attribué.

Aussi, dans votre deuxième exemple, qui supprime l'objet attribué par Func1 () ? Juste parce que vous retournez une référence au lieu du pointeur ne signifie pas que la libération de la mémoire allouée se produira comme par magie.


0 commentaires

9
votes

Vous n'avez pas résolu aucune fuite de mémoire. Si vous nouvelle, vous devez supprimer. Tout ce que vous avez fait était la déréférence du pointeur, il doit encore être supprimé. Vous pouvez résoudre des fuites de mémoire en créant des objets locaux et en retournant par la valeur ou en utilisant des pointeurs intelligents. 99 fois sur 100, je préfère le retour par option de valeur.

Maintenant, comme beaucoup de débutants, l'idée de renvoyer de gros objets par valeur fait probablement effrayer votre esprit Perf-central. Lisez Ce pour apaiser vos peurs. < / p>


0 commentaires

6
votes

Votre approche n'aide pas du tout:

#include <memory>

typedef std::shared_ptr<Foo> FooPtr;

FooPtr makeFoo()
{
  // return FooPtr(new Foo);       // Baby's first smart pointer
  return std::make_shared<Foo>();  // Adult approach to shared_ptr
}

int main()
{
  FooPtr pf = makeFoo();

  someFooModifier(*pf);
}


2 commentaires

Tu n'écrivais jamais "Supprimer et variable" même si cela fonctionne dans ce cas.


Tu n'as jamais fait ce que l'Op a fait en premier lieu! (J'ai ajouté une note, cependant, merci.)



1
votes

Vous ne devez pas remplacer un pointeur propriétaire (un responsable de la suppression) avec une référence; Il est idiomatique de supposer que les références jamais, jamais fortes> possèdent la ressource référée.

// Won't have to check for 0 in the body
void
my_func1(my_class&);

std::unique_ptr<my_class>
func1()
{
    return std::unique_ptr<my_class>(new my_class);
}

int main()
{
    auto p = func1();

    func2(*p);
}


0 commentaires

2
votes

Oui, il y a une fuite de mémoire. Le code suivant est exécuté avec Valgrind : xxx


0 commentaires