cppMemDbg – Librería fácil de usar de detección de fugas de memoria para C++

Esta librería es la secuela para C++ de cMemDbg.

Tal como cMemDbg, es una librería muy fácil de usar que sirve para ayudar a detectar y trazar fugas de memoria (memory leaks).

Su utilización es muy similar a la cMemDbg, pero con soporte para los operadores de C++ (new, new[], delete and delete[]).

Hay muchas soluciones para esto en la red, pero esta tiene la particularidad de ser realmente simple de implementar.

>new  003D26D8  36  [Main.cpp:127]
>new  003D2708  36  [Main.cpp:128]
>ERROR  Bad free type  free => delete  003D2708  36
(Main.cpp:128)
>free  003D2708  36  (Main.cpp:128)  [Main.cpp:129]
>free  003D2708  0    [Main.cpp:130]
>ERROR  Trying to free unallocated memory: 003D2708
[Main.cpp:130]
>delete[]  003D3EB0  7  (String.cpp:59)  [String.h:41]
[...]
>delete[]  003D24F0  4  (String.cpp:59)  [String.h:41]
>delete  003D2490  40  (Lista.h:120)  [Lista.h:112]
>INFO  PROBLEM: Memory leak found (36 bytes)
>INFO  Unfreed block  003D26D8  36    [Main.cpp:127]

Simplemente hay que agregar el siguiente include al archivo principal de inclusión (un archivo que sea incluido por cada archivo del proyecto) o, en el caso de que no haya uno, a cada archivo que llame a una función de alocación de memoria (malloc, realloc, calloc, free, new, new[], delete or delete[]).

Esta es la línea:

#include "cMemDbg.h"

Hay dos precauciones extra a tener en cuenta:
1- Incluirlo después de los headers standard (stdio.h, stdlib.h, malloc.h, etc.).
2- Nunca llamar al aperador delete (o delete[]) sin saber si su argumento es NULL. Así que “delete a;” debería pasar a ser “if (a) delete a;”. De otro modo, la librería puede mostrar mensajes incorrectos.

Eso es todo… Esperabas más? Bueno, hay un último paso… Tenés que hacer esta llamada justo antes de salir del programa para poder obtener las conclusiones detalladas:

PrintMemoryLeakInfo();

Por defecto, la salida de la librería irá a stdout (normalmente la pantalla de la consola). Si querés redirigira a un archivo, podés llamar a la función InitCPPMemDbg(). Este es su prototipo:

void InitCPPMemDbg(const char *pszOutputPath = NULL);

Otra opción, para simplificar, es crear un objeto global del tipo “cppMemDbg” al comienzo de las declaraciones globales. Podés pasarle una ruta de archivo al constructor para redirigir la salida. Este objeto se va a encargar de llamar automáticamente a InitCPPMemDbg (para configurar la redirección) al construirse y a PrintMemoryLeakInfo al destruirse.

Así de simple:

cppMemDbg cDbg;

O, con redirección:

cppMemDbg cDbg("mylocalfile.txt");

Easy, not?

That was all… Really.

Fácil, no?

Eso fue todo… En serio.

GNU GPL v3 cppMemDbg está liberado bajo la licencia GNU GPL v3 (attached)…

Ahora, antes de ir a funcionalidades más “de experto”, voy a dejar el link para descargar la librería para aquellos que no quieran seguir leyendo:

Ahora continuemos…

Esta librería viene con tres parámetros configurables (disponibles en cppMemDbg.cpp):

  • PRINT_OPERATIONS: Si está seteado en 1, se va a imprimir a la salida configurada (stdout por default) cada operación de alocación de memoria realizada en el programa (alocación o liberación). De otro modo, la librería sólo imprimirá problemas, notificaciones y el dump final. [Valor predeterminado = 1]
  • MAX_ALLOC: Largo del stack interno de memoria de la librería (en elementos). Es la máxima cantidad de alocaciones que pueden ser trazadas sin ser liberadas. Se puede incementar este valor a voluntad en casi de ser necesario. De hecho, si es necesario, la librería imprimirá un mensaje diciendo: “INTERNAL_ERROR: Allocation stack overflow, please increase MAX_ALLOC”. [Valor predeterminado = 256]
  • g_fFile: FILE* al cuál escribirle todas las notificaciones generadas por la librería. [Valor predeterminado = stdout]
  • MAX_DELETE_STACK: Largo del stack interno de delete de la librería (en elementos). Es la máxima cantidad de deletes que pueden anidarse. Se puede incementar este valor a voluntad en casi de ser necesario. De hecho, si es necesario, la librería imprimirá un mensaje diciendo: “INTERNAL_ERROR: Delete stack overflow, please increase MAX_DELETE_STACK”. [Valor predeterminado = 16]

Finalmente, hay dos funciones más que se pueden utilizar en caso de ser necesario:

  • PrintTotalAllocatedMemory(): Imprime la cantidad acumulativa de memoria alocada al momento de la llamada.
  • PrintMemoryReservedByCMemDbgLibrary(): Imprime la cantidad de memoria reservada por la librería (definida en tiempo de compilación por la constante MAX_ALLOC).

Eso es todo… Dije que era fácil de usar.

De todos modos si, luego de leer los comentarios del archivo cMemDbg.h, tenés algún tipo de pregunta, comentario o sugerencia, no dudes en contactarme.

Acá está el proyecto Control de Asistencia modificado para verificar la existencia de memory leaks y problemas de alocación/liberación de memoria con la librería cppMemDbg:

El código es portable entre Linux y Windows (lo testeé personalmente en ambas plataformas y funcionó idénticamente).

Ha sido desarrollado, compilado y testeado utilizando wxDev-C++ para Windows con el compilador MinGW (incluído en el paquete). En Linux, fue compilado utilizando el compilador GNU GCC.

Está configurado para enviar la salida al archivo “TestMemDbg.txt” del directorio actual. Esta es la parte importante del archivo Main.cpp:

//...

#include "ControlDeAsistencia.h"
#include "BasicFunctions.h"
#include <fstream>

#include "cppMemDbg.h"

cppMemDbg cDbg("TestMemDbg.txt");

//...

Y esta es su salida satisfactoria (la salida real está tabulada para hacer más simple su análisis utilizando un software de hoja de cálculos):

>new[]  003D3F58  14  [String.cpp:59]
>new[]  003D2438  14  [String.cpp:59]
>delete[]  003D3F58  14  (String.cpp:59)  [String.h:41]
>new[]  003D3EB0  7  [String.cpp:59]
>new[]  003D2450  7  [String.cpp:59]
[...]
>delete[]  003D2558  4  (String.cpp:59)  [String.h:41]
>delete[]  003D24F0  4  (String.cpp:59)  [String.h:41]
>delete  003D2490  40  (Lista.h:120)  [Lista.h:112]
>INFO  No memory leaks detected

Support appreciated!

All the content offered in this website is, except noted otherwise, of free nature. This means you can share it wherever you want if you do it freely and stating its source.

If it was useful for you and you’d like to contribute, you can make a donation or, at least, visit one of our advertisers of your choice; they are all around the site.

Incoming search terms for the article:



1 Responses to “cppMemDbg – Librería fácil de usar de detección de fugas de memoria para C++”


  • hi,

    i was just trying out your mem leak detector. but when i was trying, i run into the problem the memory detector becomes not notified if the delete operator has been called to an object.

    i tried to debug the problem and the behaviour is that the overloaded new operator becomes called correctly, but the overloaded delete/delete[] becomes not called and therefore it will not do any cleanup of internal vlaues.

    did you ever seen that behaviour??

    I’m working at with:
    Windows 7
    Eclipse (Indigo)
    MinGW 4.4

    Thanks
    Michael

Leave a Reply