2008-11-25 9 views
5

Tengo un vector con 1000 "nodos"Cambio de la reserva de memoria de C++ vector

if(count + 1 > m_listItems.capacity()) 
    m_listItems.reserve(count + 100); 

El problema es que también está claro que cuando estoy a punto de volver a llenarlo.

m_listItems.clear(); 

La capacidad no cambia. He utilizado el cambio de tamaño (1); pero eso no parece alterar la capacidad. Entonces, ¿cómo se cambia la reserva?

+0

¿Su sistema tiene poca memoria? Reservar así significa que agregarle n elementos usa O (n^2) tiempo y como máximo n + 100 objetos por valor de espacio más error de redondeo. Permitir que el vector se extienda sería menos código, O (n) tiempo, y en la mayoría de las implementaciones usar como máximo 2 * n espacio más redondeo. –

+0

Mi sistema tiene muy poca memoria. (Embebido) .. El código era realmente solo un ejemplo de lo que estoy pensando implementar. En general, obtengo 1000 fragmentos de elementos de la "tabla", por lo que tiene sentido cambiar el tamaño en la misma frecuencia. La LIMPIEZA fue mi principal preocupación. – baash05

Respuesta

20
vector<Item>(m_listItems).swap(m_listItems); 

se reducirá m_listItems nuevo: http://www.gotw.ca/gotw/054.htm (Herb Sutter)

Si desea borrar todos modos, intercambio con un vector vacío:

vector<Item>().swap(m_listItems); 

que por supuesto es la forma más eficiente. (Tenga en cuenta que intercambiar vectores básicamente significa simplemente intercambiar dos punteros. Nada que consuma mucho tiempo)

+2

Vale la pena señalar que mientras swap() es extremadamente barato, la construcción de la copia temporal de m_listItems en el primer caso va a requerir la copia de cada elemento en el vector. Entonces, limpiar el vector por completo (establecer la capacidad en 0) es barato. Reducirlo de otro modo no lo es. – jalf

+1

jalf de hecho. pero esa secuencia es esencialmente la misma que sería necesaria si el vector tuviera una función de contracción(). la reasignación sería necesaria de todos modos:/ –

+1

pero su punto es bueno, ya que en C++ 1x, los vectores pueden mover sus elementos al nuevo lugar. mi código debería simplemente mirar el vector (std :: move (m_listItems)). swap (m_listItems); entonces creo que –

1

usted podría intentar esta técnica de here

std::vector<int> v; 
// ... fill v with stuff... 
std::vector<int>().swap(v); 
1

Puede swap con un nuevo vector que ha deseado la capacidad.

vector<int> tmp; 
old.swap(tmp); 
1

Por lo que puedo ver, no puede reasignar un vector a una capacidad inferior a la que tiene; solo puedes asignarlo más grande. Hay buenas razones para esto; entre ellos, el proceso de reasignación es enormemente intensivo desde el punto de vista computacional. Si realmente necesita un vector más pequeño, libere el viejo y cree uno nuevo que sea más pequeño. Eso es computacionalmente mucho más simple que tener el vector realmente cambiar de tamaño más pequeño.

+0

¿cómo lo liberas? – baash05

+0

Depende de cómo se haya asignado, ya sea que lo deje fuera del alcance o que llame a eliminar. No creo que este sea un buen consejo en comparación con el intercambio. –

2

, se puede intercambiar el vector como han sugerido otros, y como se describe en http://www.gotw.ca/gotw/054.htm pero tenga en cuenta que se trata de no libre, que está realizando una copia de cada elemento, ya que el vector tiene que asignar una nueva, más pequeña , pedazo de memoria, y copia todos los contenidos anteriores. (La operación de intercambio es esencialmente libre, pero usted está intercambiando con un temporal inicializado con una copia de los datos del vector original, que es no libre)

Si usted sabe de antemano el tamaño del vector es, usted debe asignar el tamaño adecuado para empezar, por lo que no es necesario el cambio de tamaño:

std::vector<foo> v(1000); // Create a vector with capacity for 1000 elements 

Y si usted no sabe la capacidad de anticipación, por qué es importante si se pierde un poco de espacio? ¿Vale la pena el tiempo dedicado a copiar cada elemento a un vector nuevo y más pequeño (que es lo que hará std :: vector (v) .swap (v)), solo para ahorrar algunos kilobytes de memoria?

Del mismo modo, cuando borre el vector, si tiene la intención de volver a llenarlo de todos modos, establecer su capacidad a cero parece ser una pérdida de tiempo impresionante.

Edición:

baash05: ¿Y si tuviera 1000000 artículos otros 10 megas de ram.¿Diría reduciendo la cantidad de gastos generales es importante?

No. Cambiar el tamaño del vector requiere más la memoria, de manera temporal, por lo que si eres de memoria limitada, que podría romper su aplicación. (Debe tener el vector original en la memoria, y el temporal, antes de poder intercambiarlos, por lo que termina usando hasta el doble de RAM en ese punto). Después, puede guardar una pequeña cantidad de memoria (hasta un par de MB), pero esto no importa, porque nunca se accederá al exceso de capacidad en el vector, por lo que sería empujado al archivo de paginación, por lo que no cuente hacia su límite de RAM en primer lugar.

Si tiene 1000000 elementos, entonces debe inicializar el vector al tamaño correcto en primer lugar.

Y si no puede hacer eso, entonces será mejor que deje la capacidad solo. Especialmente desde que declaró que va a volver a llenar el vector, definitivamente debe reutilizar la capacidad que ya ha sido asignada, en lugar de asignar, reasignar, copiar y liberar todo constantemente.

Tiene dos posibles casos. O sabe cuántos elementos necesita almacenar o no. Si lo sabe, puede crear el vector con el tamaño correcto en primer lugar, y así nunca tendrá que cambiarle el tamaño, o no lo sabe, y entonces también podría mantener el exceso de capacidad, por lo menos no tendrá que cambiar el tamaño hacia arriba cuando rellene su vector.

+0

¿y si tuviera 1000000 artículos y 10 megas de ram? ¿Diría que es importante reducir la cantidad de sobrecarga? – baash05

+0

No, por lo general. Ver mi edición – jalf

Cuestiones relacionadas