2010-11-04 10 views
15

¿Este código causará una pérdida de memoria?¿Qué sucede con la memoria asignada por `new` si el constructor lanza?

#include <stdexept> 

class MyClass 
{ 
public: 
    MyClass() 
    { 
     throw std::runtime_error("Test"); 
    } 
}; 

int main() 
{ 
    try 
    { 
     MyClass * myClass = new MyClass; 
    } 
    catch (const std::exception & exc) 
    { 
     // Memory leak? 
    } 
    return 0; 
} 

La memoria asignada por new nunca se elimina. ¿Esto se soluciona internamente, o es una pérdida de memoria real?

Respuesta

16

La memoria se liberará automáticamente antes de que la excepción se propague.

Esto es esencial, porque a) el programa nunca recibe un puntero a libre, yb) incluso si lo hiciera, no tendría forma portátil de liberarlo ya que la memoria nunca se convirtió en un objeto que puede eliminar.

12

La memoria se desasignará correctamente.

Preguntas relacionadas en SO.

  • Is it ever not safe to throw an exception in a constructor?
  • C++ : handle resources if constructors may throw exceptions (Reference to FAQ 17.4)
  • [email protected] ~ $ cat noleak.cpp && g++ noleak.cpp && valgrind --leak-check=full ./a.out 
    #include <stdexcept> 
    
    class MyClass 
    { 
    public: 
        MyClass() 
        { 
         throw std::runtime_error("Test"); 
        } 
    }; 
    
    int main() 
    { 
        try 
        { 
         MyClass * myClass = new MyClass; 
        } 
        catch (const std::exception & exc) 
        { 
         // Memory leak? 
        } 
        return 0; 
    } 
    ==3652== Memcheck, a memory error detector 
    ==3652== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
    ==3652== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info 
    ==3652== Command: ./a.out 
    ==3652== 
    ==3652== 
    ==3652== HEAP SUMMARY: 
    ==3652==  in use at exit: 0 bytes in 0 blocks 
    ==3652== total heap usage: 3 allocs, 3 frees, 106 bytes allocated 
    ==3652== 
    ==3652== All heap blocks were freed -- no leaks are possible 
    ==3652== 
    ==3652== For counts of detected and suppressed errors, rerun with: -v 
    ==3652== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6) 
    [email protected] ~ $ 
    
    +1

    +1 para probarlo con Valgrind. – DarkDust

    4

    $ 15,2/2 - "Un objeto que es parcialmente construidos o parcialmente destruidos tendrá destructores ejecutados para todos de sus clases base totalmente construidos y miembros no variantes, es decir, para los subobjetos cuyo principal constructor (12.6.2) ha completado la ejecución y el destructor no tiene pero ha comenzado la ejecución. De forma similar, si el constructor no delegante para un objeto ha completado la ejecución y existe un que delega el constructor para ese objeto , se invocará el destructor del objeto. Si el objeto se asignó en una nueva expresión , la función de desasignación correspondiente (3.7.4.2, 5.3.4, 12.5), si corresponde, se llama para liberar el almacenamiento ocupado por el objeto. "

    Cuestiones relacionadas