Que yo sepa, uno puede asignar elementos a un std::vector
de dos maneras:
vec[i] = value
vec.push_back(value)
Sin embargo, el primer método no parece tener efecto en vec.size()
, y también se sobrescribe con llamadas posteriores a vec.push_back()
. Un ejemplo mínimo para demostrar:
#include <iostream>
#include <vector>
int main()
{
std::vector<unsigned char> things;
things.reserve(2);
things[0] = 'a';
std::cout << "Size after inserting a: ";
std::cout << things.size() << std::endl;
things.push_back('b');
std::cout << "Size after inserting b: ";
std::cout << things.size() << std::endl;
std::cout << "Contents: ";
for (int i=0; i<2; i++)
{
std::cout << things[i] << std::endl;
}
return 0;
}
La salida de este programa es:
Size after inserting a: 0
Size after inserting b: 1
Contents: b
Entonces, ¿podría alguien explicarme:
¿Por qué el tamaño es 0 incluso después de insertar
'a'
?¿Por qué
things.push_back('b')
sobrescribe la'a'
?
Nota: Estoy usando unsigned char
porque he adaptado este código de un programa que estoy escribiendo que involucra la manipulación de este tipo.
Gracias de antemano.
3 respuestas
reserve
en realidad no cambia el tamaño del vector. Solo cambia la capacidad del vector, que es diferente de su tamaño real (consulte aquí para obtener una explicación de lo que realmente es). Por lo tanto, su llamada de things[0] = 'a';
ha pasado el tamaño del vector, ya que todavía tiene el tamaño 0 y, por lo tanto, un comportamiento indefinido.
Si llamas a resize
en su lugar, obtienes esto:
Size after inserting a: 2
Size after inserting b: 3
Contents: a
Ahora el vector contiene un 'a'
, un '\0'
y un 'b'
. '\0'
está ahí porque ese es el valor predeterminado de unsigned char
, por lo que things.resize(2);
deja el vector con dos de ellos antes de cambiar uno a 'a'
.
Una información más
std::vector<unsigned char> things;
things.reserve(2);
Debajo de la asignación, sin verificar los límites del vector, escribirá en la memoria señalada por cosas [0]. Esta operación nunca falla pero causa un comportamiento indefinido debido a la corrupción de la memoria.
things[0] = 'a'; // 1
Debajo de la asignación, verifique los límites del vector antes de escribir en la memoria señalada por las cosas [0]. Falla si el índice no está dentro del límite del vector y genera la excepción 'std :: out_of_range'.
things.at(0) = 'a' //2
- No lo insertó, lo asignó a un elemento que no existe. Esto tiene un comportamiento indefinido. La asignación no extiende el vector.
- Como el vector estaba vacío,
push_back
agregó el primer elemento.
Nuevas preguntas
c++
C ++ es un lenguaje de programación de propósito general. Originalmente fue diseñado como una extensión de C, y tiene una sintaxis similar, pero ahora es un lenguaje completamente diferente. Use esta etiqueta para preguntas sobre el código (que se compilará) con un compilador de C ++. Utilice una etiqueta específica de la versión para preguntas relacionadas con una revisión estándar específica [C ++ 11], [C ++ 14], [C ++ 17] o [C ++ 20] etc.