Question

Je veux trouver des fuites de mémoire dans mon application à l'aide des utilitaires standard. Auparavant, j'utilisé ma propre mémoire allocateur, mais d'autres personnes (oui, vous AlienFluid) a suggéré d'utiliser l'application de Microsoft Verifier, mais je ne peux pas sembler l'obtenir pour signaler mes fuites. J'ai la simple application suivante:

#include <iostream>
#include <conio.h>

class X
   {
   public:
      X::X() : m_value(123) {}
   private:
      int m_value;
   };

void main()
{
X *p1 = 0;
X *p2 = 0;
X *p3 = 0;

p1 = new X();
p2 = new X();
p3 = new X();
delete p1;
delete p3;
}

Ce test contient clairement une fuite de mémoire. P2 est new'd mais pas supprimé

I construire l'exécutable en utilisant les lignes de commande suivantes:

cl /c /EHsc /Zi /Od /MDd test.cpp
link /debug test.obj

J'ai téléchargé Application Verifier (4.0.0665) et a permis à tous les contrôles.

Si je lance maintenant ma demande de test je peux voir un journal en application Verifier, mais je ne vois pas la fuite de mémoire.

Questions:

  • Pourquoi ne Application Verifier signaler une fuite?
  • Ou ne Application Verifier vraiment destiné à détecter les fuites?
  • Si ce n'est pas que d'autres outils sont disponibles pour signaler clairement les fuites à la fin de l'application (et non en prenant des instantanés réguliers et en les comparant car cela est impossible dans une application de prise de 1 Go ou plus), y compris l'appel pile du lieu d'affectation (donc pas la déclaration de simple fuite à la fin du tube cathodique)

Si je ne trouve pas un utilitaire décent, je dois encore compter sur mon propre gestionnaire de mémoire (ce qui fait parfaitement).

Était-ce utile?

La solution

mémoire CRT détection de fuites (sans trace de la pile):

// debug_new.h
#pragma once

#include "crtdbg.h"

#ifdef _DEBUG
#ifndef DEBUG_NEW
#define DEBUG_NEW   new( _NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#endif

Tous les fichiers .cpp:

#include "debug_new.h"

...

// After all other include lines:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

...

Ecrire cette fois dans le code d'initialisation du programme:

_CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

Dans MFC, tout cela est déjà mis en œuvre dans les en-têtes MFC. Vous ne devez vous assurer que tous les fichiers cpp contient ces lignes:

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

Restrictions:. Ce que les prises de fuites de mémoire « nouvelles », toutes les fuites, causées par une autre fonction, comme malloc, ne sont pas pris

Ne pas faire des allocations à l'intérieur des fichiers .h -. Ils seront imprimés sans lignes de source, car DEBUG_NEW est défini après toutes les lignes #include

Autres conseils

Application Verifier ne capture que des fuites dans les DLL. Essayez de lire l'info-bulle dans la case de fuite. C'est ce qu'il dit.

J'ai le sentiment que l'application Verifier cas particuliers, le chemin de sortie et ne pas signaler ces fuites comme -. Après tout, tout le tas de processus est libre à la sortie de processus

Essayez d'écrire un autre exemple où vous initialisez le même pointeur à nouveau - en fait perdre la référence à l'allocation précédente. Cela devrait certainement être signalé. Permettez-moi de connaître les résultats.

En outre, AppVerifier (si vous avez toutes les options activées) devrait également prendre Dépassements de tampon, sousverses, écrivant à empiler les endroits marqués RO etc.

Mémoire Validator de vérification du logiciel attrapera les fuites de mémoire, et de montrer la callstack complète de l'allocation de la fuite. Bien qu'il soit un produit commercial, il a une période d'essai afin programmeurs peuvent essayer et voir si elle vaut le prix pour eux.

La solution la plus simple est ne pas écrire les fuites ou les dépassements de tampon en premier lieu - les détecter après l'événement est vraiment un gaspillage d'efforts. Dans mon propre code, depuis des années, j'ai eu zéro problèmes dans ces domaines. Pourquoi? Becauase J'utilise les mécanismes C ++ fournit de les éviter. Par exemple:

X *p1 = 0;
p1 = new X();

devrait être:

shared_ptr <X>  p1 = new X();

et vous ne vous inquiétez pas au sujet de la fuite p1. Mieux encore, ne pas utiliser l'allocation dynamique du tout:

X x1;

Pour les dépassements de tampon, utilisez toujours des types comme std :: string qui va croître sur l'entrée, ou si elles ne poussent pas détectera le débordement possible et vous avertir.

Je ne suis pas se vanter de mes prouesses pour éviter les fuites de mémoire - ce genre de choses ne fonctionne vraiment pas, et vous permet de vous concentrer sur la tâche beaucoup plus difficile de débogage business logique de votre code.

Détecteur de fuites visuel (de v2.2) est plus utile que le CRT Library de débogage, car il affiche le callstack complet utilisé pour l'allocation de mémoire a conduit à la fuite.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top