2012-05-05 15 views
31

Estoy totalmente confundido con respecto a la eliminación de cosas en C++ Si declaro una matriz de objetos y si uso la función clear(). ¿Puedo estar seguro de que la memoria fue lanzada?C++ borrar vector, objetos, memoria libre

Por ejemplo:

tempObject obj1; 
tempObject obj2; 
vector<tempObject> tempVector; 

tempVector.pushback(obj1); 
tempVector.pushback(obj2); 

¿Puedo llamar de forma segura clara para liberar toda la memoria? ¿O necesito iterar para eliminar uno por uno?

tempVector.clear(); 

Si este escenario se cambia a un puntero de objetos, ¿la respuesta será la misma que la anterior?

+1

No hay nada diferente del segundo caso que el primer caso que no sea el hecho de que señala un vector. Creo que esta pregunta debe ampliarse para que pueda entender cómo debería funcionar la asignación/desasignación de memoria, y probablemente también los indicadores. – Marlon

+0

Este dice que declararlo dentro de una pila de funciones llama automáticamente al destructor al cierre. https://stackoverflow.com/questions/3054567/right-way-to-deallocate-an-stdvector-object –

Respuesta

62

Puede llamar a borrar, y eso destruirá todos los objetos, pero eso no liberará la memoria. Bucle a través de los elementos individuales no servirá de nada (lo que la acción qué incluso proponer a asumir los objetos?) Lo que puede hacer es la siguiente:

vector<tempObject>().swap(tempVector); 

que va a crear un vector vacío sin memoria asignada e intercambiarlo con tempVector, desasignando de manera efectiva la memoria.

C++ 11 también tiene la función shrink_to_fit, que podría llamar después de la llamada a borrar(), y teóricamente reduciría la capacidad para ajustarse al tamaño (que ahora es 0). Sin embargo, esta es una solicitud no vinculante, y su implementación puede ignorarla.

+0

Hola, gracias por la respuesta. ¿te importa explicar lo que dice el anterior? después de llamar eso, ¿necesito llamar a clear? – mister

+3

@dupdupdup: No, no es necesario que llame sin problemas. Los objetos que estaban en tempVector se transfieren al vector vacío. Luego, el vector vacío, dado que es un objeto temporal sin nombre, se destruye y su contenido, que anteriormente era propiedad de tempVector, se destruye y la memoria se desasigna. –

+0

No soy un experto en C++, me importa explicar cómo es mejor que 'tempVector.resize (0)' ¿Lo intentaría primero? – delnan

14

vector::clear() no libera la memoria asignada por el vector para almacenar objetos; llama destructores para los objetos que contiene.

Por ejemplo, si el vector se utiliza una matriz como un almacén de respaldo y actualmente contiene 10 elementos, entonces llamar clear() llamará al destructor de cada objeto en la matriz, pero la matriz de soporte no se desasignado, así que hay todavía es sizeof(T) * 10 bytes asignados al vector (al menos). size() será 0, pero size() devuelve la cantidad de elementos en el vector, no necesariamente el tamaño de la tienda de respaldo.

En cuanto a su segunda pregunta, nada se puede asignar con new debe desasignar con delete. Por lo general, no mantiene un puntero a un vector por este motivo. Rara vez (si alguna vez) hay una buena razón para hacer esto e impide que el vector se limpie cuando sale del alcance. Sin embargo, llamar al clear() seguirá actuando de la misma forma independientemente de cómo se haya asignado.

18

Hay dos cosas separadas aquí:

  1. objeto vida
  2. duración de almacenamiento

Por ejemplo:

{ 
    vector<MyObject> v; 
    // do some stuff, push some objects onto v 
    v.clear(); // 1 
    // maybe do some more stuff 
} // 2 

En 1, que claro v: esto destruye toda los objetos que estaba almacenando. Cada uno recibe su destructor llamado, si lo escribió, y todo lo que pertenece a ese MyObject ahora se ha liberado. Sin embargo,, vector v tiene derecho a mantener el almacenamiento sin procesar en caso de que lo desee más tarde.

Si decide introducir más elementos entre 1 y 2, ahorra tiempo ya que puede volver a utilizar la memoria anterior.

En 2, el vector v sale del ámbito: cualquier objeto que empuja en él desde 1 serán destruidos (como si hubieras llamado explícitamente claro una vez más), pero ahora el almacenamiento subyacente también se libera (v won' estar cerca para reutilizarlo más).


Si cambio el ejemplo de modo v se convierte en un puntero, es necesario eliminar de forma explícita, como el puntero de salir del ámbito en 2 no hacer eso por usted. Es mejor usar algo como std::unique_ptr en ese caso, pero si no lo hace y se filtra v, también se filtrará el almacenamiento que asignó. Como se indicó anteriormente, debe asegurarse de que v se elimine, y llamar al clear no es suficiente.

+0

¿Qué quiere decir con 'Si decide presionar ... esto ahorra tiempo ya que puede reutilizar el viejo recuerdo'? ¿Por qué importa la memoria antigua cuando desea agregar nuevos elementos? – user13107

+0

El vector tiene que administrar el almacenamiento internamente para los objetos que almacena. Crear un nuevo vector requiere asignar nuevo almacenamiento, pero borrar y reutilizar un vector existente permite (pero no garantiza) la reutilización de su almacenamiento ya asignado. – Useless

0

Si necesita utilizar el vector una y otra vez y su código actual lo declara repetidamente dentro de su bucle o en cada llamada de función, es probable que se quede sin memoria. Sugiero que se declara fuera, pasarlas como punteros en sus funciones y su uso:

my_arr.resize() 

esta manera, se sigue usando la misma secuencia de memoria para sus vectores en lugar de solicitar nuevas secuencias cada vez. Espero que esto haya ayudado. Nota: cambiar el tamaño a diferentes tamaños puede agregar valores aleatorios. Pase un número entero como 0 para inicializarlos, si es necesario.

Cuestiones relacionadas