tutorial online library array c++ c++11 memory-leaks stdvector

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>());