Seminario web destacado: Pruebas de API mejoradas con IA: un enfoque de prueba sin código | Vea ahora

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

Foto de cabeza de Arthur Hicken, evangelista de Parasoft
2 de agosto de 2023
3 min leer

Debido a la abundancia de datos, las fugas de memoria en el desarrollo de software pueden ser difíciles de identificar. Esta publicación le enseñará cómo usar un programa de detección de errores en tiempo de ejecución para encontrar pérdidas de memoria en C y C++.

Las fugas 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 cómo encontrar pérdidas 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.

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 cadena variable hasta ahora apunta a la cadena "hola" que se asignó como resultado de la iteración de bucle 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:

Ejemplo de pérdida de memoria.

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 fugaDescripción
SIN FUGASOcurre cuando libera un bloque de memoria que contiene punteros a otros bloques de memoria.
FUGA_RETURNOcurre cuando una función devuelve un puntero a un bloque de memoria asignado, pero el valor devuelto se ignora en la rutina de llamada.
FUGA_SCOPEOcurre 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 de verificación de pérdida de memoria C++,  Obtenga más información sobre Parasoft Insure ++ aquí.

Detección y visualización de errores en tiempo de ejecución y memoria con Parasoft Insure ++