vectors remove pushback how delete c++ stl vector memory-management

c++ - remove - Forma "correcta" de desasignar un objeto std:: vector



vector vector c++ (12)

Aunque ambos parecen funcionar, no veo ninguna razón para no llamar simplemente eliminar en el puntero. El vector debe tener un destructor llamado que manejará todo lo demás.

La primera solución es:

std::vector<int> *vec = new std::vector<int>; assert(vec != NULL); // ... delete vec;

Una alternative es:

std::vector<int> v; //... vec.clear(); vec.swap(std::vector<int>(vec));

La segunda solución es un truco. ¿Cuál es la forma "correcta" de hacerlo?

Actualizar:

Soy consciente de que se llamará al destructor una vez que esté fuera de la pila, tenía curiosidad sobre otros métodos.


Delete desasigna la memoria, la memoria queda libre para el próximo objeto pero el vector se ha ido.

El segundo truco libera cualquier exceso de memoria pero deja el vector intacto, pero vacío.


En el caso de que el vector realmente necesite estar en el montón, no olvide:

std::auto_ptr<std::vector<int> > vec(new std::vector<int>);

especialmente útil con código como:

std::auto_ptr<std::vector<int> > vec(vectorFactoryFunction());


Esta no es una comparación válida porque los ejemplos tratan con diferentes tipos de objetos: duración dinámica y duración local. Puedes llamar al destructor O usar el truco de intercambio (también conocido como shrink_to_fit) con cualquiera de ellos. El camino correcto depende de si necesita que el vector objeto persista o no.

Por ejemplo, puede necesitar que persista si hay referencias o indicadores que deben seguir siendo válidos, en cuyo caso la reducción es la única forma, independientemente de cómo se haya asignado.


Estoy de acuerdo con Mike Seymour, prueba esto, entonces notarás que el último está funcionando bien

const int big_size = 10000; vector<double> v( big_size ); cout << "Before clearing, the capacity of the vector is " << v.capacity() << " and its size is " << v.size(); v.clear(); cout << "/nAfter clearing, the capacity of the vector is " << v.capacity() << " and its size is " << v.size(); vector<double>().swap( v ); cout << "/nAfter swapping, the capacity of the vector is " << v.capacity() << " and its size is " << v.size(); vector<double> v1( big_size ); v1 = vector<double>(); cout << "/n After vector<double>();, the capacity of the vector is " << v1.capacity() << " and its size is " << v1.size();


La forma más simple de desasignar todo el almacenamiento en un vector, sin destruir el objeto vectorial en sí, es

vec = std::vector<int>();

Su segunda variante tendrá el mismo efecto, pero salta a través de más aros en el camino. El truco "copiar y intercambiar" desasigna cualquier capacidad adicional del vector y puede ser útil si contiene algunos datos que desea conservar. Si no hay datos, entonces no hay necesidad de copiar o intercambiar.


La forma más simple y confiable de desasignar un vector es declararlo en la pila y simplemente no hacer nada.

void Foo() { std::vector<int> v; ... }

C ++ garantiza que se llamará al destructor de v cuando se ejecute el método. El destructor de std::vector asegurará que cualquier memoria asignada sea liberada. Siempre que el tipo T del vector<T> tenga una semántica de desasignación C ++ adecuada, todo estará bien.


No estoy seguro de por qué su segundo ejemplo utiliza un constructor de copia para el constructor temporal en lugar de un constructor predeterminado. Eso le ahorraría la línea de código .clear() .

Puede hacer esto genérico para cualquier objeto, incluso si no es un contenedor. Supongo que std :: swap está especializado para llamar a vector :: swap.

template<typename T> void ResetToDefault(T & value) { std::swap(T(), value); } std::vector<int> vec; //... ResetToDefault(vec);


No use funciones de asignación de memoria a menos que realmente lo necesite. Si su clase necesita un vector, siempre, simplemente adquiera directamente el miembro std :: vector. No es necesario hacer la asignación de memoria aquí.

En los casos en que necesita el vector dinámico, asignarlo y eliminarlo como en su primer ejemplo es 100% correcto.

En el segundo ejemplo, la llamada a std :: swap se dice estrictamente que no es necesaria, ya que el método clear borrará el vector y lo dejará vacío. Un posible problema es que no hay garantía de que el vector realmente libere la memoria y la devuelva al sistema operativo (o al tiempo de ejecución). El vector puede mantener la memoria asignada solo en caso de que llene el vector justo después de borrarlo. La llamada a std :: swap puede ser un truco para "forzar" al vector a liberar sus datos internos, pero no hay garantía de que esto realmente suceda.


Si solo deja que el vector salga del alcance, se limpiará a sí mismo de manera adecuada sin trabajo adicional. Si el vector es una variable miembro de una clase, y desea desasignar su contenido antes de que su propietario sea destruido, simplemente llame a vec.clear ().

Si desea mantener el vector pero desasignar la memoria que contiene su contenido, entonces vec.swap(std::vector<int>()); lo haré. No es necesario copiar y construir el temporal en el original a menos que el vec contenga elementos que desee conservar y solo desee reducir la memoria asignada a algo cercano al tamaño actual ().


Supongo que tienes un vector que contiene una gran cantidad de datos temporalmente. Una vez que el vector ha sido borrado, aún ocupará toda esta memoria. Desea liberar esta memoria después de que haya terminado con ella, pero la función / objeto con el que está trabajando no ha terminado.

Soluciones en orden decreciente de deseabilidad:

  1. Vuelva a trabajar el código para que el vector que usa el código esté en su propio bloque / función / objeto para que se destruya naturalmente
  2. Utilice el truco de intercambio, de esta manera no tiene que preocuparse por asegurarse de que el vector se desasigna en todas las circunstancias. Su vida estará ligada al objeto / función en el que se encuentre.
  3. nuevo / eliminar el vector. Esto liberará un poco más de memoria que el método anterior, pero también es más difícil asegurarse de que no se haya filtrado ninguna memoria.

La única diferencia técnica entre el intercambio y la eliminación es que el vector base no se destruye. Esta es una pequeña sobrecarga y no vale la pena preocuparse (siempre y cuando finalmente destruyas el vector)

La consideración más importante es la que hace que sea más fácil escribir el código correcto, y creo que el intercambio gana sobre borrarlo, pero es peor que mover el vector a otro lugar.


std::vector<int> vi; /*push lots of stuff into the vector*/ // clean it up in C++03 // no need to clear() first std::vector<int>().swap(vi); // clean it up in C++0x // not a one liner, but much more idiomatic vi.clear(); vi.shrink_to_fit();