2010-01-24 14 views
6

Estaba buscando a través del código std :: vector y encontré algo que no acababa de obtener. Cuando la capacidad < size() + 1 necesita reasignar el buffer para que pueda insertar el nuevo elemento. Lo que hace (por lo que he sido capaz de extraer del código) es:std :: vector insert() reasignación

  • asignar la nueva memoria intermedia
  • copiar el prefijo de la antigua memoria intermedia (0 - índice de inserción)
  • construir el nuevo elemento en el nuevo buffer
  • copiar el sufijo de la antigua memoria intermedia (índice - final)
  • llamada al destructor en todos los artículos en tampón de edad
  • búfer de edad deallocate

La copia de prefijo y sufijo se realiza con memmove por lo que pude ver. ¿No es Memmove una copia pura de los datos? No llama al constructor de los elementos, ¿verdad? Lo que me preguntaba es, ¿por qué la función llama al destructor en los elementos en el viejo buffer si la memoria simplemente se mueve, no se reconstruye en el nuevo buffer?

+1

Creo que su comprensión del código es incorrecta. Si cree que se está utilizando memmove, publique un fragmento que ilustre esto. –

+0

El uso de memmove es una posible optimización del compilador. Pero su nosotros solo es válido para los tipos de POD. Si el tipo tiene un constructor/destructor, deben ser utilizados. –

Respuesta

5

Miré a través de la implementación de MSVC8 vector - No puedo ver un memmove(). Los elementos vectoriales anteriores no se mueven, se copian y se llama a su controlador de copia para copiarlos en el nuevo búfer (el búfer se asigna en una sola asignación, los elementos se construyen usando la colocación nueva).

Por supuesto, esta es solo la implementación de MSVC, pero así es como debería comportarse un vector de acuerdo con la norma.

Sin embargo, utilizar memmove a veces es correcto, por ejemplo para std::vector<int>, y las implementaciones de STL son gratuitas para especializarse en este caso. Es posible que haya perdido una plantilla 'rama' leyendo el código fuente.

+0

Sí, lo hice. Estaba viendo la especialización . ¡Gracias! –

+0

Me pregunto si sería igualmente válido 'swap (viejo, nuevo)' en lugar de construir y destruir. –

+0

No creo que 'swap' sea válido porque requiere que' old' y 'new' estén completamente construidos, lo que no ocurre con el buffer de destino. Sin embargo, con C++ 11, 'std :: move' en lugar de' std :: copy' está bien. –