246 votes

Comment trouver la fuite de mémoire dans un code C++/projet?

Je suis programmeur C++ sur la plate-forme windows. Je suis à l'aide de Visual studio 2008.

J'ai l'habitude de retrouver dans le code avec fuite de mémoire.

Normalement je trouve la fuite de mémoire par normalement en inspectant le code, mais il est lourd et n'est pas une bonne approche toujours.

Puisque je ne peux pas les moyens de payé fuite de mémoire de l'outil de détection. Je voulais vous les gars pour suggérer le mieux possible pour éviter la fuite de mémoire

  1. Je voulais savoir comment le programmeur peut trouver de fuite de mémoire.
  2. Est-il une norme ou procédure, on doit suivre pour s'assurer il n'y a pas de fuite de mémoire dans le programme.

365voto

John Smith Points 1211

Instructions

Les choses dont Vous aurez Besoin

  • La compétence en C++
  • Compilateur C++
  • Débogueur et d'autres outils logiciels d'enquête

1

Comprendre les notions de base de l'opérateur. L'opérateur C++ "nouvelle" alloue de la mémoire de masse. La "suppression" de l'opérateur libère la mémoire du tas. Pour chaque "nouveau", vous devez utiliser un "supprimer" afin de libérer la mémoire alloué:

char* str = new char [30]; // Allocate 30 bytes to house a string.

delete [] str; // Clear those 30 bytes and make str point nowhere.

2

Réallouer la mémoire que si vous avez supprimé. Dans le code ci-dessous, str acquiert une nouvelle adresse avec la deuxième allocation. La première adresse est irrémédiablement perdu, et sont donc les 30 octets qu'il souligné. Maintenant, ils sont impossibles à free, et vous avez une fuite de mémoire:

char* str = new char [30]; // Give str a memory address.

// delete [] str; // Remove the first comment marking in this line to correct.

str = new char [60]; /* Give str another memory address with
                                                    the first one gone forever.*/

delete [] str; // This deletes the 60 bytes, not just the first 30.

3

Regarder ces pointeur de missions. Chaque variable dynamique (mémoire allouée sur le tas) doit être associé à un pointeur. Lorsqu'une variable dynamique devient dissocié de son pointeur(s), il devient impossible à effacer. De nouveau, ce qui entraîne une fuite de mémoire:

char* str1 = new char [30];

char* str2 = new char [40];

strcpy(str1, "Memory leak");

str2 = str1; // Bad! Now the 40 bytes are impossible to free.

delete [] str2; // This deletes the 30 bytes.

delete [] str1; // Possible access violation. What a disaster!

4

Soyez prudent avec les pointeurs locaux. Un pointeur de vous déclarer, dans une fonction est alloué sur la pile, mais la dynamique de la variable, il est alloué sur le tas. Si vous ne la supprimez pas, elle persiste après les sorties de programme à partir de la fonction:

void Leak(int x){

char* p = new char [x];

// delete [] p; // Remove the first comment marking to correct.

}

5

Attention à la place des accolades après "supprimer". Utilisation "supprimer" par lui-même afin de libérer un objet unique. Utilisation "supprimer" [] avec des crochets pour gratuit un tas de tableau. Ne pas faire quelque chose comme ceci:

char* one = new char;

delete [] one; // Wrong

char* many = new char [30];

delete many; // Wrong!

6

Si la fuite encore admis - je suis habituellement recherchant avec deleaker (vérifier ici: http://deleaker.com).

Merci!

37voto

Nawaz Points 148870

Vous pouvez utiliser certaines techniques dans votre code pour détecter les fuites de mémoire. Le plus commun et le plus facile moyen de le détecter est, de définir une macro dire, DEBUG_NEW et de l'utiliser, avec des macros prédéfinies comme __FILE__ et __LINE__ pour localiser la fuite de mémoire dans votre code. Ces macros prédéfinies vous dire le fichier et le numéro de ligne de fuite de mémoire.

DEBUG_NEW est juste une MACRO qui est habituellement définie comme:

#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW

De sorte que, partout où vous utilisez new, il peut aussi garder une trace du fichier et le numéro de ligne qui pourrait être utilisé pour localiser les fuites de mémoire dans votre programme.

Et __FILE__, __LINE__ sont des macros prédéfinies qui permettent d'évaluer pour le nom de fichier et le numéro de ligne respectivement, où que vous les utilisez!

Lire l'article suivant qui explique la technique de l'utilisation de DEBUG_NEW avec d'autres intéressant les macros, très joliment:

Une Croix-Plate-Forme De Détecteur De Fuite De Mémoire


De Wikpedia,

Debug_new se réfère à une technique en C++ de surcharge et/ou la redéfinition de l'opérateur nouvelle et l'opérateur delete pour intercepter l'allocation de mémoire et la désallocation des appels, et ainsi de débogage programme pour l'utilisation de la mémoire. Il est souvent implique la définition d'une macro nommée DEBUG_NEW, et fait de nouveaux devenir quelque chose comme neuf(_FICHIER_, _LIGNE_) pour enregistrer le fichier/ligne d'informations sur l'allocation. Microsoft Visual C++ utilise cette technique de Microsoft Les Classes De Base. Il y a quelques les moyens d'étendre cette méthode à éviter à l'aide de macro redéfinition tout encore en mesure d'afficher le fichier/ligne informations sur certaines plates-formes. Il y de nombreux limitations inhérentes à ce la méthode. Elle s'applique uniquement aux C++, et ne peut pas détecter les fuites de mémoire en C des fonctions comme la fonction malloc. Cependant, il peut être très simple à utiliser et aussi très rapide, comparativement à certains plus mémoire complète débogueur solutions.

16voto

Doc Brown Points 13438

Il y a certains bien connus des techniques de programmation qui va vous aider à réduire le risque d'avoir des fuites de mémoire à portée de main:

  • si vous avez à faire votre propre allocation dynamique de la mémoire, écrire new et delete toujours par paires, et assurez-vous que l'allocation/désallocation de code est appelé par paires
  • éviter d'allocation dynamique de la mémoire si vous le pouvez. Par exemple, utilisez vector<T> où que possible au lieu de T[]
  • utiliser des "pointeurs intelligents" comme auto_pointer ou booster les pointeurs intelligents (http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/smart_ptr.htm)
  • mon favori personnel: assurez-vous d'avoir bien compris le concept de propriété d'un pointeur, et assurez-vous que partout où vous utilisez les pointeurs, vous connaissez le code de l'entité est le propriétaire
  • apprendre que les constructeurs / opérateurs d'affectation sont créés automatiquement par le compilateur C++, et ce que cela signifie si vous avez de la classe qui possède un pointeur (ou ce que cela signifie si vous avez une classe qui contient un pointeur vers un objet qui n'est pas propre).

10voto

CantGetANick Points 902

6voto

Arrabi Points 1556

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X