2012-03-18 7 views
6

Si tenemos map <int, vector<int> > se mueven cuando el árbol rojo-negro del mapa cambia o almacena punteros a vector so algo así y no los mueve (de lo contrario, trabajar con mapas no será O (lg n) por ejemplo, si ya nos push_back elementos a algunos vector s)¿Es estable la segunda parte del mapa <..,..>?

Respuesta

9

Ver esta: std::map, pointer to map key value, is this possible?

la segundo respuesta más común:

Sección 23.1.2 # 8 (con asociativa requisitos de tainer):

"Los miembros de inserción no afectarán la validez de los iteradores y las referencias al contenedor, y los miembros de borrado invalidarán únicamente los iteradores y las referencias a los elementos borrados".

Así punteros almacenamiento a los miembros de datos de un elemento del mapa está garantizada para ser válido, a menos que quite que elemento.

Por lo tanto, si se conservan las referencias, los datos no se pueden copiar en una parte diferente de la memoria. Y si ese es el caso, no veo el punto de realizar ninguna copia ...

+0

Esto no aborda la pregunta principal: ¿'std :: map' está permitido para _move_ elements? –

+0

Si un elemento se movió, un puntero/referencia a él se invalidaría (estoy hablando de punteros simples, no iteradores). Es por eso que no, no está permitido mover elementos. ... bueno, en teoría, alguna implementación podría copiar el objeto en algún lugar y luego regresar a la posición anterior, pero eso sería algo extraño. – CygnusX1

+0

Aunque, curiosamente, no se hace tal requisito de 'borrar '. –

1

No, los vectores no se moverán. Las manipulaciones del árbol simplemente reorganizan punteros entre los nodos. No mueven los nodos o sus contenidos en la memoria.

1

Creo que el C++ 03 no ofrece ninguna garantía de estabilidad de los datos en la memoria, y esto sería un detalle de implementación (y en realidad no es algo que pueda asumir sin pruebas).

Tenga en cuenta que la preservación de los iteradores al mapa y la ubicación del vector real en la memoria son cosas completamente diferentes. La validez de los iteradores está claramente definida (tanto cuando son válidos como cuando no lo son) en la especificación C++, pero el comportamiento interno real del árbol no lo está.

Dicho esto, cualquier compilador decente (para compilaciones de versión/con optimizaciones habilitadas) optimizaría la implementación para no copiar realmente el vector cuando se mueve en el árbol, y las implementaciones de C++ 11 de std::map usarían semántica de movimiento para garantizar ese comportamiento.

Lo que no puede asumir es que internamente solo se mueven los punteros.

+1

'std :: map ' debe estar un contenedor basado en nodos en todas las revisiones del estándar, es decir,los nodos que no se borran del mapa permanecen en la memoria: ni los iteradores ni los punteros para asignar los elementos se invalidan hasta que se borre el nodo o se destruya el mapa. –

+0

Pero también conserva las referencias (indicadores simples), no solo los iteradores. Esto te permite discutir sobre la memoria. A menos que haya alguna extraña virtualización de direcciones de memoria ... – CygnusX1

Cuestiones relacionadas