Encontrar una pérdida de memoria en C o C ++

Por Arthur Hiken

28 de junio de 2018

3  min leer

A diferencia de la imagen de arriba, las pérdidas de memoria en el software de programación pueden ser difíciles de identificar porque hay una gran cantidad de datos. En este artículo, puede aprender a encontrar fugas de memoria en aplicaciones C y C ++ con la ayuda de una herramienta de detección de errores en tiempo de ejecución.

¿Qué es una pérdida de memoria? Ejemplos de C ++ y C

Cuando se enfrenta a una pérdida de memoria, C ++ y C tienen un conjunto de herramientas de detección en tiempo de ejecución que pueden ayudar con el rendimiento. Aquellos que escriben código en C o C ++ estarán familiarizados con las pérdidas de memoria. Wikipedia ofrece la siguiente definición:

En ciencias de la computación, una pérdida de memoria es un tipo de pérdida de recursos que ocurre cuando un programa de computadora administra incorrectamente las asignaciones de memoria de tal manera que la memoria que ya no se necesita no se libera. También puede ocurrir una pérdida de memoria cuando un objeto se almacena en la memoria pero el código en ejecución no puede acceder a él.

En otras palabras, las fugas significan que la memoria asignada dinámicamente no se puede devolver al sistema operativo porque el programa ya no contiene punteros que puedan acceder a ella. Ha perdido el control de esa pieza de memoria independientemente del tamaño y ya no puede acceder a ella ni liberarla.

Obtenga el depurador de memoria definitivo para C y C ++.
Prueba Parasoft Insure ++

Uno de los mejores ejemplos de este comportamiento se puede ver ejecutando el programa "Hola mundo" que se muestra a continuación.

   
/ * * Archivo: hello.c * / #include #incluir int main (int argc, char * argv []) {char * string, * string_so_far; int i, longitud; longitud = 0; para (i = 0; i

Si ejecutamos este programa con los siguientes argumentos:

hola esto es una prueba

Si examinamos el estado del programa en la línea 25, justo antes de ejecutar la llamada a malloc por segunda vez, observamos:

  • La variable string_so_far apunta a la cadena "hola" que fue asignada como resultado de la iteración del ciclo anterior.
  • La cadena variable apunta a la cadena extendida "hola esto" que se asignó en esta iteración de bucle.

Estas asignaciones se muestran esquemáticamente a continuación; ambas variables apuntan a bloques de memoria asignada dinámicamente.

La siguiente declaración:

cadena_hasta_ahora = cadena;

creará ambas variables apuntando al bloque de memoria más largo como se muestra a continuación:

Sin embargo, una vez que esto sucede, no queda ningún puntero que apunte al bloque más corto. Incluso si quisiera, no hay forma de que se pueda reclamar la memoria a la que anteriormente apuntaba string_so_far; ahora está asignado de forma permanente. Esto se conoce como "pérdida de memoria". C ++ y C enfrentan estos problemas comunes a menudo, por lo que es importante detectarlos temprano.

¿Cómo se detecta una pérdida de memoria en C ++ y C?

Si bien no hay un botón para "detectar pérdida de memoria", C ++ & c tienen herramientas de detección en tiempo de ejecución que pueden ayudar. Este tipo de error se puede diagnosticar mediante herramientas de detección de errores de memoria, como Parasoft Insure ++. Esto se muestra a continuación:

[hola.c: 25] ** LEAK_ASSIGN ** >> string_so_far = string; Memoria filtrada debido a la reasignación del puntero: cadena Bloque perdido: 0x0804bd68 a través de 0x0804bd6f (8 bytes) cadena, asignada en hello.c, 15 malloc () (interfaz) main () hello.c, 15 Seguimiento de pila donde ocurrió el error: main ( ) hola c, 25

Este ejemplo se llama LEAK_ASSIGN porque se produce cuando se reasigna un puntero. (PD: Otros depuradores de memoria a menudo no hacen una distinción entre memoria sobresaliente y memoria filtrada real, pero Insure ++ sí lo hace). En este caso, la memoria sobresaliente no es memoria que es asombrosa, es memoria que no liberaste, a diferencia de una fuga real que es memoria que no puede liberar.

Tipos de pérdidas de memoria

Parasoft Insure ++ también puede detectar varios otros tipos de fugas automáticamente:

Tipo de fuga Descripción
SIN FUGAS Ocurre cuando libera un bloque de memoria que contiene punteros a otros bloques de memoria.
LEAK_RETURN Ocurre cuando una función devuelve un puntero a un bloque de memoria asignado, pero el valor devuelto se ignora en la rutina de llamada.
LEAK_SCOPE Ocurre cuando una función contiene una variable local que apunta a un bloque de memoria, pero la función regresa sin guardar el puntero en una variable global o devolvérselo a su llamador.

Tenga en cuenta que el mensaje de error indica la línea de origen exacta en la que se produce el problema, no solo dónde se asignó el bloque, que es un tema clave para encontrar y reparar pérdidas de memoria. Esto es extremadamente importante porque es fácil introducir pérdidas de memoria sutiles en sus aplicaciones, pero es muy difícil encontrarlas todas.

Si está buscando una herramienta C ++ de verificación de fugas de memoria, puede obtener una prueba gratuita de Parasoft Insure ++.

Por Arthur Hiken

Arthur ha estado involucrado en seguridad de software y automatización de pruebas en Parasoft durante más de 25 años, ayudando a investigar nuevos métodos y técnicas (incluidas 5 patentes) mientras ayuda a los clientes a mejorar sus prácticas de software.

Reciba las últimas noticias y recursos sobre pruebas de software en su bandeja de entrada.