Because an int is (usually) 4 bytes 65
will fit quite neatly into just the first byte and the rest of the memory allocated for the int will be 0
this byte pattern happens to match up very closely to how strings are stored in memory.
So when the memory is accessed through a char*
it will print A
most of the time even though most of the prints were ill formed
int v = 65; // Byte pattern on most machines [65,0,0,0]
int* q = &v;
char** o = (char**)&q; // *o now points to [65,0,0,0] ==> ['A','\0','\0','\0'] ==> "A"
std::cout << o << std::endl;
// input: char**
// printed as: pointer
// result: 012FFCAC
std::cout << *o << std::endl; // Undefined Behaviour
// input: char*
// printed as: null terminated string
// result: "A"
std::cout << **o << std::endl; // Undefined Behaviour
// input: char
// printed as: single character
// result: 'A'
printf("%c",*o); // %c expects a [char] type but is given [pointer to char] ERROR
printf("%p",*o); // %p expects a [pointer] type and is given a [pointer to char] OK
Since a char
is (usually) 1 byte there is no null terminand to stop the printing once it starts and it keeps printing whatever is around in memory until it runs into a 0
or an access violation
char v = 65;
std::cout << &v << std::endl; // &v is not a well-formed null terminated string: Undefined Behaviour
// input: char*
// printed as: null terminated string
// result: "A<whatever other data is around v in memory>"