0

The following code :

int number = 65;
char *ptr = reinterpret_cast< char* >(&number);
cout << *ptr << endl;

*ptr prints A and ptr prints A. Why do they both print the same result ?

2 Answers2

4

The streams are overloading << such that the dereferencing is done implicitly for char anyway.

More specifically: Since char * is the string of C, ostream tries to read it as such, i.e. it dereferences the pointer and reads chars until it finds a zero byte. (This works only for the correct Endianness.)

Consider this code:

#include <iostream>

int main(void) {
        char c = 'A';
        int  i = 66;
        std::cout <<  c << '\n';
        std::cout << &c << '\n';
        std::cout <<  i << '\n';
        std::cout << &i << '\n';
        return 0;
}

On my machine (Not on all!) it prints

A
AB
66
0x7fff0d1db1bc

because c is printed correctly, but &c is interpreted as string. But cis not null-terminated so ostream continues reading, finding the first byte of i and then finally a null byte, since the value of i is so small we only use one of its four bytes.

However, i and &i are printed as expected. This behaviour is only implemented for char as it makes no sense for other types.

Hermann Döppes
  • 1,373
  • 1
  • 18
  • 26
1

Both print the same result because:

  1. ostream::operator<< has, among others, an overload for char* and char (see here and here).
  2. The char* overload interprets the argument as a pointer to a null-terminated byte string, opposed to as a pointer to a single char.
  3. Apparently your machine is little endian and has sizeof(char) < sizeof(int) (opposed to ==). That means that the memory occupied by number, when interpreted as an array of chars, is a char of value 65 followed by one or more null chars. Thus when number is interpreted as a null-terminated byte string, it contains a single character of value 65.

Thus when you stream *ptr, which is of type char, the char overload prints the character pointed which has value 65. When you stream ptr, which is of type char*, the char* overload prints the null-terminated byte string pointed to, which contains a single character of value 65, so again the single character is printed.

Further Notes regarding point 3:

Note that given sizeof(char) < sizeof(int) you're guaranteed to get a null-terminated byte string with exactly one character in it because CHAR_BIT is at least 8. I.e. it's not possible that the value 65 does not fit into a single char.

Maybe your machine has sizeof(char) == sizeof(int) (in which case the endianess doesn't matter), and it's just coincidence that the memory after number is a null character, building again a thing which looks like a null-terminated byte string. I say looks like because it only really is one if you're allowed to read the terminating null character. Since on most systems CHAR_BIT is 8 (which is required by POSIX), and since the standard requires int to be at least 32 bits, it's highly unlikely that your machine has sizeof(char) == sizeof(int).

Community
  • 1
  • 1
Florian Kaufmann
  • 803
  • 6
  • 13