Printing addresses of vector's elements shows garbage [duplicate]

This question already has an answer here:


Why does streaming a char pointer to cout not print an address?

4 answers




Consider:

#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;
}


Sample output for the code above is:

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


For every primitive data types memory locations are contiguous, except for char. It prints some garbage value on the screen.

I tried adding v.reserve(4), but the output was the same.


For every primitive data types memory locations are contiguous, except
for char. It prints some garbage value on screen.


The "memory locations" are contiguous in the exact same way for both cases. The only difference is how you're displaying your results. When you do:

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


you're giving std::operator<<(std::basic_ostream) a char*, as you're applying & (address-of) on a single char1 from the vector, which makes it treat it as a C-style string -- meaning, it looks for a terminating null. In your case, this null is right after some garbage indeed. But you're bound to have some garbage after the vector<int> just as well, only you're not printing it.

If you want to get the same printout as you're getting for the vector<int>, then you could explicitly cast to a void pointer, so std::cout will treat it as an address to be printed (overload (7) here), not a string:

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


In which case the output is:

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& to be precise, as std::vector<T>::operator[] returns a T&.

std::vector<T>::operator[]() returns T&, address of which in case of char will be formatted by overload (2) of operator<<(std::basic_ostream) as if it was a null terminated C-style string (that is a string that begins at &vChar[i] and stops at the first \0 found).

To make it work use std::cout << static_cast<const void*>(&vChar[i]) to pick up overload (7) of std::basic_ostream::operator<<().

Comments

Popular posts from this blog

Meaning of `{}` for return expression

Get current scroll position of ScrollView in React Native

flutter websocket connection issue