c++ - online - Seguro de usar vector.emplace_back(nuevo MyPointer); ¿Podría el fallo dentro del vector conducir a la pérdida de memoria?
array library c++ (2)
No es seguro y crearía una pérdida de memoria si usa la primera versión. La documentación dice que si se lanza una excepción, la llamada a emplace
no tiene ningún efecto, lo que significa que el puntero simple que pasó no se borrará nunca.
Puedes usar
vector.emplace_back( std::unique_ptr<MyPointer>( new MyPointer() ) );
o con C ++ 14 puedes usar
vector.emplace_back( std::make_unique<MyPointer>() );
o, si C ++ 14 todavía no está disponible, simplemente despliegue su propia versión de make_unique
. Puedes encontrarlo aquí .
¿Es seguro usarlo?
vector.emplace_back( new MyPointer() );
¿O podría una excepción lanzada o alguna falla dentro del vector causar una fuga de memoria?
¿Sería mejor hacer alguna forma de lo siguiente, donde coloca el puntero en un unique_ptr temporal primero?
vector.emplace_back( std::unique_ptr<MyPointer>( new MyPointer() ) );
Entonces, si ocurre una falla de vector, el unique_ptr temporal aún limpiará la memoria.
No, el primer escenario no es seguro y perderá memoria si el vector
arroja una excepción.
El segundo escenario no se compilará, ya que std::unique_ptr<T>
no se puede convertir implícitamente en T*
. Incluso si pudiera, este escenario es posiblemente peor que el primero, porque agregará el puntero a su vector, y luego eliminará inmediatamente el objeto al que apunta. Te quedarás con un vector que contiene un puntero colgante.
Sin cambiar el tipo de su std::vector
(que supongo que es std::vector<MyPointer*>
) hay dos maneras de hacer que esta excepción de código sea segura.
Usando C ++ 11:
auto ptr = std::unique_ptr<MyPointer>(new MyPointer());
vector.emplace_back(ptr.get());
ptr.release();
O la forma más detallada de C ++ 03:
MyPointer* ptr = new MyPointer();
try
{
vector.push_back(ptr);
}
catch (...)
{
delete ptr;
throw;
}
Si puede cambiar el tipo de su std::vector<MyPointer*>
, el método más sencillo es el sugerido por Daniel Frey:
std::vector<std::unique_ptr<MyPointer>> vector;
vector.emplace_back(std::unique_ptr<MyPointer>(new MyPointer()));
O con C ++ 14:
std::vector<std::unique_ptr<MyPointer>> vector;
vector.emplace_back(std::make_unique<MyPointer>());