objetos - recorrer una lista c++
¿Es seguro acceder al puntero sin formato después de std:: vector:: reserve? (3)
Esto es bastante descabellado, pero el siguiente código es "seguro" (es decir, garantiza que no causa fallas de segmentación):
std::vector<int> vec(1); // Ensures that &vec[0] is valid
vec.reserve(100);
memset(&vec[0], 0x123, sizeof(int)*100); // Safe?
Me doy cuenta de que esto es feo, solo me interesa saber si es técnicamente seguro, no "bonito". Supongo que su único uso podría ser ignorar los valores almacenados más allá de un índice determinado.
¡Nota! ¿Cómo puedo obtener la dirección del buffer asignado por vector :: reserve ()? cubre el mismo tema, pero estoy más interesado si esto es seguro y si hay trampas haciendo esto.
EDIT: el código original fue incorrecto, reemplazó el memcpy
original con memset
.
La reasignación de vectores invalida punteros, referencias, etc. existentes . Reserve podría desencadenar una reasignación (23.3.6.2, [vector.capacity]) pero está tomando la dirección del primer elemento después de la reasignación eventual (que en este caso probablemente no ocurra en todo, pero eso es además del punto). Entonces no veo ningún problema con el código.
No, no es seguro.
Después de una reserve()
, se garantiza que el vector no reasignará el almacenamiento hasta que se alcance la capacity()
.
Sin embargo, la norma no indica qué puede hacer la implementación del vector con el almacenamiento entre size()
y capacity()
. Tal vez se pueda usar para algunos datos internos, ¿quién sabe? ¿Tal vez el espacio de direcciones está reservado y no está asignado a la RAM real?
El acceso a elementos fuera de [0..size] es un comportamiento indefinido. Podría haber algún control de hardware para eso.
Primero tenga en cuenta que su memset
truncará el 0x123
a un solo byte y lo escribirá, sin escribir un patrón de cuatro bytes.
Entonces, no hagas eso, solo usa el contenedor: std::vector<int> vec(100, whatever_value_you_want);
Sin embargo, para responder a la pregunta, puede parecer que funciona específicamente para tipos de POD si el compilador no utiliza el espacio asignado para nada. Ciertamente, si alguien llama a push_back
, insert
, push_back
, etc., volará lo que ya ha escrito en la memoria y el tamaño del vector también será incorrecto. Simplemente no hay razón para escribir dicho código.