Creo que mallinfo() es lo que quieres:
#include <malloc.h>
struct mallinfo *info;
info = mallinfo();
printf ("total allocated space: %llu bytes\n", info->uordblks);
printf ("total free space: %llu bytes\n", info->fordblks);
La estructura struct mallinfo es técnica y específica de la implementación malloc(). Pero la información que desea está ahí. Así es como informo los valores:
mallinfo.arena = "Total Size (bytes)"
mallinfo.uordblks = "Busy size (bytes)"
mallinfo.fordblks = "Free size (bytes)"
mallinfo.ordblks = "Free blocks (count)"
mallinfo.keepcost = "Top block size (bytes)"
mallinfo.hblks = "Blocks mapped via mmap() (count)"
mallinfo.hblkhd = "Bytes mapped via mmap() (bytes)"
Estos dos supuestamente no se usan, pero parecen cambiar en mi sistema y, por lo tanto, podrían ser válidos:
mallinfo.smblks = "Fast bin blocks (count)"
mallinfo.fsmblks = "Fast bin bytes (bytes)"
Y el otro valor interesante lo devuelve "sbrk (0)"
Hay varias posibilidades.
¿Qué tan preciso necesitas que sea? Puede obtener algunos datos útiles a través de cat /proc/${PID}/status | grep VmData .
Puedes #definir tu propio malloc() , realloc() , calloc() y gratis() funciones, envolviendo las funciones reales detrás de su propio mostrador. Puede hacer cosas realmente geniales aquí con __FILE__, __LINE__ y __func__ para facilitar la identificación de fugas de núcleo en pruebas simples. ¡Pero solo instrumentará su propio código!
(Del mismo modo, también puede redefinir el operador nuevo predeterminado y borrar operador métodos, variantes de matriz y no matriz, y ambas lanzando variantes std::bad_alloc y std::nothrow_t. De nuevo, ¡esto solo instrumentará su propio código!)
(Tenga en cuenta:en la mayoría de los sistemas C++, nuevo finalmente invoca malloc() . No tiene que hacerlo. Especialmente con nuevo en el lugar ! Pero normalmente nuevo hace uso de malloc() . (O opera en una región de la memoria que previamente ha sido malloc()'ed .) De lo contrario, se involucraría en cosas realmente raras con múltiples administradores de montones...)
Puedes usar sbrk(0) para ver dónde está configurado actualmente el segmento de datos. Eso no es tan bueno. Es una medida muy aproximada y no tiene en cuenta los agujeros (regiones de memoria no utilizadas) en el montón. (Está mucho mejor con VmData línea de /proc/${PID}/status .) Pero si solo buscas una idea general...
Puede atrapar malloc()/free()/etc escribiendo su propia biblioteca compartida y obligando a su proceso a usarla en lugar de las versiones reales a través de LD_PRELOAD . Puede usar dlopen()/dlsym() para cargar e invocar el *real* malloc()/free()/etc . Esto funciona muy bien. El código original no se modifica, ni siquiera se vuelve a compilar. Pero tenga en cuenta las situaciones de reingreso al codificar esta biblioteca, y que su proceso invocará inicialmente malloc()/calloc()/realloc() antes de dlopen()/dlsym() puede completar la carga de las funciones reales.
Puede consultar herramientas como Valgrind , aunque en realidad está más dirigido a las fugas de memoria.
Por otra parte, tal vez mtrace() es lo que quieres? O __malloc_hook ? Muy patentado (GNU) y no estándar... Pero está etiquetado como "Linux"...
No hay nada fácil, automático manera de hacerlo, si eso es lo que estás preguntando. Básicamente, debe realizar un seguimiento manual de las asignaciones de almacenamiento dinámico utilizando una variable de contador. El problema es que es difícil controlar qué partes de su programa están asignando memoria en el montón, especialmente si está usando muchas bibliotecas fuera de su control. Para complicar aún más las cosas, hay dos formas en que un programa puede asignar memoria de montón:new
o malloc
. (Sin mencionar las llamadas directas al sistema operativo como sbrk
.)
Puede anular el operador global new
, y haga que cada llamada aumente una cuenta global. Sin embargo, esto no incluirá necesariamente los momentos en que su programa llame a malloc
, o cuando su programa usa algún new
específico de clase anular. También puede anular malloc
usando una macro, pero esto no es necesariamente portátil. Y también tendría que anular todas las variaciones de malloc
, como realloc
, calloc
, etc. Todo esto se complica aún más por el hecho de que en algunas implementaciones, new
en sí mismo puede llamar a malloc
.
Entonces, esencialmente, es muy difícil hacer esto correctamente desde dentro de su programa. Recomendaría usar una herramienta de perfilado de memoria en su lugar.