¿Cómo puedo obtener el tamaño de un bloque de memoria asignado usando malloc ()?

Posibles duplicados:
¿Cómo puedo obtener el tamaño de una matriz desde un puntero en C?
¿Hay alguna manera de determinar el tamaño de una matriz de C ++ programáticamente? Y si no, ¿por qué?

Obtengo un puntero a un trozo de memoria asignada de una función de estilo C. Ahora, sería muy interesante para la depuración saber cuán grande es el bloque de memoria asignado que señala este puntero.

¿Hay algo más elegante que provocar una excepción corriendo ciegamente sobre sus límites?

Gracias de antemano, Andreas

EDITAR:

Uso VC ++ 2005 en Windows y GCC 4.3 en Linux

EDIT2:

Tengo _msize en VC ++ 2005 Desafortunadamente resulta en una excepción en el modo de depuración ….

EDIT3:

Bien. Intenté la manera que describí arriba con la excepción, y funciona. Al menos mientras estoy depurando y asegurándome de que inmediatamente después de que la llamada a la biblioteca salga, ejecute los límites del buffer. Funciona de maravilla.

Simplemente no es elegante y de ninguna manera se puede usar en el código de producción.

No es estándar, pero si su biblioteca tiene una función msize () que le dará el tamaño.

Una solución común es ajustar malloc con su propia función que registra cada solicitud junto con el tamaño y el rango de memoria resultante, en la versión de lanzamiento puede volver al malloc ‘real’.

Si no te importa la violencia de mala calidad por el bien de la depuración, puedes # definir macros para enganchar llamadas a malloc y liberar y rellenar los primeros 4 bytes con el tamaño.

Por el valor de

 void *malloc_hook(size_t size) { size += sizeof (size_t); void *ptr = malloc(size); *(size_t *) ptr = size; return ((size_t *) ptr) + 1; } void free_hook (void *ptr) { ptr = (void *) (((size_t *) ptr) - 1); free(ptr); } size_t report_size(ptr) { return * (((size_t *) ptr) - 1); } 

entonces

 #define malloc(x) malloc_hook(x) 

y así

La biblioteca de tiempo de ejecución de C no proporciona esa función. Además, provocar deliberadamente una excepción tampoco te dirá qué tan grande es el bloque.

Por lo general, la forma en que se resuelve este problema en C es mantener una variable separada que realiza un seguimiento del tamaño del bloque asignado. Por supuesto, esto a veces es inconveniente, pero generalmente no hay otra manera de saberlo.

Su biblioteca de tiempo de ejecución de C puede proporcionar algunas funciones de depuración de montón que pueden consultar los bloques asignados (después de todo, free() necesita saber qué tan grande es el bloque), pero cualquiera de este tipo de cosas será no portable.

Con gcc y el GNU linker , puede ajustar malloc fácilmente

 #include  #include  void* __real_malloc(size_t sz); void* __wrap_malloc(size_t sz) { void *ptr; ptr = __real_malloc(sz); fprintf(stderr, "malloc of size %d yields pointer %p\n", sz, ptr); /* if you wish to save the pointer and the size to a data structure, then remember to add wrap code for calloc, realloc and free */ return ptr; } int main() { char *x; x = malloc(103); return 0; } 

y comstackr con

 gcc ac -oa -Wall -Werror -Wl,--wrap=malloc 

(Por supuesto, esto también funcionará con el código de C ++ comstackdo con g ++, y con el nuevo operador (a través de su nombre destrozado) si lo desea).

En efecto, la biblioteca cargada estáticamente / dinámicamente también usará su __wrap_malloc .

No, y no puede confiar en una excepción cuando sobrepasa sus límites, a menos que esté en la documentación de su implementación. Es parte de las cosas que realmente no necesita saber para escribir progtwigs. Adéntrate en la documentación de tu comstackdor o código fuente si realmente quieres saber.

No hay una función C estándar para hacer esto. Dependiendo de su plataforma, puede haber un método no portátil: ¿qué biblioteca de sistema operativo y C está utilizando?

Tenga en cuenta que provocar una excepción no es confiable: puede haber otras asignaciones inmediatamente después del fragmento que tiene, por lo que es posible que no obtenga una excepción hasta mucho después de superar los límites de su fragmento actual.

Los comprobadores de memoria como Memcheck de Valgrind y TCMalloc de Google (la parte del comprobador de montones ) hacen un seguimiento de este tipo de cosas.

Puede usar TCMalloc para volcar un perfil de stack que muestra dónde se asignaron las cosas, o simplemente puede hacer que verifique para asegurarse de que su stack sea la misma en dos puntos en la ejecución del progtwig usando SameHeap () .

Solución parcial: en Windows puede usar PageHeap para capturar un acceso de memoria fuera del bloque asignado.

PageHeap es un administrador de memoria alternativo presente en el kernel de Windows (en las variedades NT pero nadie debería usar ninguna otra versión hoy en día). Toma cada asignación en un proceso y devuelve un bloque de memoria que tiene su extremo alineado con el final de una página de memoria, luego hace que la siguiente página sea inaccesible (sin lectura, sin acceso de escritura). Si el progtwig intenta leer o escribir más allá del final del bloque, obtendrá una infracción de acceso que puede detectar con su depurador favorito.

Cómo obtenerlo: descargue e instale el paquete Herramientas de depuración para Windows de Microsoft: http://www.microsoft.com/whdc/devtools/debugging/default.mspx

luego, inicie la utilidad GFlags, vaya a la tercera pestaña e ingrese el nombre de su ejecutable, luego presione la tecla. Marca la checkbox PageHeap, haz clic en Aceptar y listo.

Lo último: cuando haya terminado con la depuración, no olvide volver a ejecutar GFlags y deshabilite PageHeap para la aplicación. GFlags ingresa esta configuración en el Registro (en HKLM \ Software \ Microsoft \ Windows NT \ CurrentVersion \ Image Execution Options \), por lo que es persistente, incluso después de reiniciar.

Además, tenga en cuenta que el uso de PageHeap puede boost enormemente las necesidades de memoria de su aplicación.

La forma de hacer lo que quieres es SER el asignador. Si filtra todas las solicitudes y luego las graba para depurarlas, entonces puede averiguar qué quiere cuando la memoria está libre.

Además, puede consultar al final del progtwig para ver si se liberaron todos los bloques asignados, y si no, enumerarlos. Una biblioteca ambiciosa de este tipo podría incluso tomar los parámetros FUNCTION y LINE a través de una macro para que sepa exactamente dónde tiene la fuga de memoria.

Finalmente, MSVCRT de Microsoft proporciona un montón depurable que tiene muchas herramientas útiles que puede usar en su versión de depuración para encontrar problemas de memoria: http://msdn.microsoft.com/en-us/library/bebs9zyz.aspx

En Linux, puede usar valgrind para encontrar muchos errores. http://valgrind.org/