programacion limpiar imprimir caracteres cadenas cadena basura arreglos arreglo c++ vector c++17

c++ - limpiar - imprimir un vector en c



Las direcciones de impresión de los elementos del vector<char> muestran basura (2)

Esta pregunta ya tiene una respuesta aquí:

Considerar:

#include <vector> #include <string> #include <iostream> using namespace std; int main() { vector<char> vChar; vChar.push_back(''a''); vChar.push_back(''b''); vChar.push_back(''c''); vChar.push_back(''d''); vector<int> vInt; vInt.push_back(1); vInt.push_back(2); vInt.push_back(3); vInt.push_back(4); cout << "For char vector Size:" << vChar.size() << " Capacity:" << vChar.capacity() << "/n"; for(int i=0; i < vChar.size(); i++) { cout << "Data: " << vChar[i] << " Address:" << &vChar[i] << "/n"; } cout << "/nFor int vector Size:" << vInt.size() << " Capacity:" << vInt.capacity() << "/n"; for (int i = 0; i < vInt.size(); i++) { cout << "Data: " << vInt[i] << " Address:" << &vInt[i] << "/n"; } return 0; }

La salida de muestra para el código anterior es:

For char vector Size:4 Capacity:4 Data: a Address:abcd²²²²αPⁿ▀┬ Data: b Address:bcd²²²²αPⁿ▀┬ Data: c Address:cd²²²²αPⁿ▀┬ Data: d Address:d²²²²αPⁿ▀┬ For int vector Size:4 Capacity:4 Data: 1 Address:000001F020F80420 Data: 2 Address:000001F020F80424 Data: 3 Address:000001F020F80428 Data: 4 Address:000001F020F8042C

Para cada tipo de datos primitivos, las ubicaciones de memoria son contiguas, excepto para char. Imprime algún valor de basura en la pantalla.

Intenté agregar v.reserve (4), pero la salida fue la misma.


Para cada tipo de datos primitivos, las ubicaciones de memoria son contiguas, excepto para char . Imprime un valor de basura en la pantalla.

Las "ubicaciones de memoria" son contiguas exactamente de la misma manera para ambos casos. La única diferencia está en cómo estás mostrando tus resultados. Cuando tu lo hagas:

cout << "Data: " << vChar[i] << " Address:" << &vChar[i] << "/n";

le está dando a std::operator<<(std::basic_ostream) un char* , ya que está aplicando & ( address-of ) en un solo char 1 del vector , lo que hace que se trate como un estilo C string - es decir, busca un nulo de terminación . En su caso, este nulo es justo después de un poco de basura. 2 Pero también está obligado a tener algo de basura después del vector<int> , solo que no lo está imprimiendo. 3

Si desea obtener la misma impresión que está obteniendo para el vector<int> , entonces puede convertir explícitamente a un puntero de void , por lo que std::cout tratará como una dirección para imprimir ( sobrecarga (7) aquí ), no una cadena:

cout << "Data: " << vChar[i] << " Address:" << static_cast<void*>(&vChar[i]) << "/n";

En cuyo caso la salida es:

For char vector Size:4 Capacity:4 Data: a Address:0x1c39810 Data: b Address:0x1c39811 Data: c Address:0x1c39812 Data: d Address:0x1c39813 For int vector Size:4 Capacity:4 Data: 1 Address:0x1c39960 Data: 2 Address:0x1c39964 Data: 3 Address:0x1c39968 Data: 4 Address:0x1c3996c

1 char& para ser preciso, como std::vector<T>::operator[] devuelve un T& .

2 Tenga en cuenta que buscar este nulo de finalización que usted no colocó allí constituye un comportamiento indefinido , ya que potencialmente le hace acceder a la memoria a la que no se pretende acceder con este fin.

3 Puede intentarlo y verlo por sí mismo si realiza la conversión inversa para hacer que std::cout trate los elementos vector<int> como cadenas de estilo C:

cout << "Data: " << vInt[i] << " Address:" << reinterpret_cast<char*>(&vInt[i]) << "/n";

Una vez más, simplemente recuerde que esto significa un comportamiento indefinido, ya que el código de impresión buscará en la memoria el nulo final, mientras que definitivamente no lo tuvo allí para que lo encuentre.


std::vector<T>::operator[]() devuelve T& , cuya dirección en el caso de char será formateada por la sobrecarga (2) del std::operator<<(std::basic_ostream) como si fuera una terminación C nula -serie de estilo (que es una cadena que comienza en &vChar[i] y se detiene en el primer /0 encontrado).

Para que funcione, utilice std::cout << static_cast<const void*>(&vChar[i]) para std::cout << static_cast<const void*>(&vChar[i]) sobrecarga (7) de std::basic_ostream::operator<<() .