[c++] Fuga de memoria C ++



Answers

Use return 0; en lugar de exit(0); al final de main . El uso de la exit evita la ejecución de los destructores.

Question

Acabo de escribir un código en C ++ que hace algo de manipulación de cadenas, pero cuando ejecuté valgrind, muestra algunas posibles pérdidas de memoria. Depurando el código a nivel granular, escribí un sencillo programa en C ++ que se ve así:

#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
        std::string myname("Is there any leaks");
        exit(0);
}

y corriendo valgrind sobre eso obtuve:

==20943== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 26 from 1)
==20943== malloc/free: in use at exit: 360,645 bytes in 12,854 blocks.
==20943== malloc/free: 65,451 allocs, 52,597 frees, 2,186,968 bytes allocated.
==20943== For counts of detected errors, rerun with: -v
==20943== searching for pointers to 12,854 not-freed blocks.
==20943== checked 424,628 bytes.
==20943== 
==20943== LEAK SUMMARY:
==20943==    definitely lost: 0 bytes in 0 blocks.
==20943==      possibly lost: 917 bytes in 6 blocks.
==20943==    still reachable: 359,728 bytes in 12,848 blocks.
==20943==         suppressed: 0 bytes in 0 blocks.
==20943== Reachable blocks (those to which a pointer was found) are not shown.
==20943== To see them, rerun with: --show-reachable=yes

Entonces me di cuenta de que nos hemos salido con fuerza (lo cual también hice en mi código C ++ original). Ahora el problema es que quiero salir del programa ya que mi código antiguo anterior espera el estado de salida del nuevo código. Por ejemplo, binary a.out espera el estado de salida de b.out. ¿Hay alguna forma de evitar las pérdidas de memoria, o debería preocuparme realmente por las pérdidas de memoria cuando el programa ya está saliendo en ese momento?

Esto también plantea otra pregunta para mí, ¿es dañino ese código?

#include<stdio.h>
#include<cstdlib>
int main()
{
        char *p=(char *)malloc(sizeof(char)*1000);
        exit(0);
}



#include<iostream>
using namespace std;
int main()
{
    {
        std::string myname("Is there any leaks");
    }
    exit(0);
}



En la mayoría de los casos, vale la pena limpiarlo después de usted mismo, por las muchas buenas razones ya dadas: mejor capacidad de mantenimiento, mejor utilidad de las herramientas de comprobación, etc.

Si hay otras razones funcionales para limpiar, tal vez sus datos se guardan en una tienda permanente, entonces no tiene otra opción: debe limpiar (aunque es posible que desee reconsiderar su diseño).

Sin embargo, en algunos casos, puede ser mejor simplemente salir y "fugarse".

Al final de un programa, su proceso va a terminar. Cuando lo haga, el sistema operativo recuperará la memoria asignada por el programa y, en algunos casos, puede hacerlo mucho más rápidamente.

Considere una gran lista vinculada, donde cada nodo se asigna dinámicamente, y lleva una estructura sustancial dinámicamente asignada. Para limpiar esto, debe visitar cada nodo y liberar cada carga útil (lo que a su vez puede provocar que se caminen otras estructuras complejas).

Puede terminar realizando millones de operaciones de memoria para ejecutar a través de dicha estructura.

El usuario quiere salir de su programa, y ​​se sientan allí por 10 segundos esperando que ocurra un montón de procesamiento de basura. No pueden estar interesados ​​en el resultado; después de todo, abandonan el programa.

Si deja que esta "fuga", el sistema operativo puede recuperar todo el bloque de memoria asignado a su proceso mucho más rápido. No le importan las estructuras ni la limpieza de objetos.

http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx

En definitiva, debe comprender lo que le dicen sus herramientas, para asegurarse de que las está utilizando correctamente.




Si desea interrumpir una ejecución y pasar un código de retorno sin superar a los destructores, genere una excepción y extraiga el valor de retorno de la excepción en main() .




Para agregar una opinión diferente.

Tal código no es dañino para todos. El sistema operativo se ocupará de todo cuando finalice el proceso. Todo lo demás da como resultado un sistema operativo inestable. Solo asegúrese de que sus datos persistentes (archivos, ...) sean consistentes.

Ir un poco más allá y afirmar provocativamente, liberar explícitamente la memoria al salir del programa puede ser dañino.

  1. La salida del programa lleva más tiempo (¿Alguna vez se molestó al esperar que un programa salga hasta que la computadora se apaga?)
  2. El orden correcto de destrucción no siempre es trivial, especialmente con componentes de terceros (recuerdo algunos programas que probablemente se bloqueen al salir)
  3. El sistema operativo puede no permitirle liberar memoria después de salir de main (*) y matar su programa en su lugar

¿Arriesgas esto solo para que Valgrind te dé un resultado específico? (**)

(*)

#include<iostream>
using namespace std;
std::string myname("Is there any leaks");
int main() {
        exit(0);
}

(**) Bueno, por supuesto, la salida de cualquier analizador de memoria es más útil sin "ruido". ¿Qué ocurre si solo liberamos memoria explícitamente al salir en modo de depuración?






Related