2

In the lesson I'm going through it uses this to record the address of a char value...

char givenChar;
std::cout<<"character = \n";
std::cin>>givenChar;

std::cout<< "address character = " << (void *) &givenChar<<"\n\n";

But it does not explain at all what is happening here to get address character = 0x7ffd812a9257.

what is the (void *) called and what is it doing?

Michael Rader
  • 5,839
  • 8
  • 33
  • 43

2 Answers2

3

To stuff something into an output-stream (std::ostream) like std::cout, the stream insertion operator << is used:

std::cout << "Hello, World!";

The stream insertion operator that is called for string literals like "Hello, World" looks like

std::ostream& operator<<(std::ostream& os, const char* s);

As you can see, the 2nd parameter is a pointer to const char. Now if you would write

char givenChar;
std::cout << &givenChar;

the address-of operator & would give you the address of givenChar. The type of this address is char* which is convertible into a char const*. So the above mentioned function

std::ostream& operator<<(std::ostream& os, const char* s);

would be called (like operator<<(std::cout, &givenChar)) which would interpret the memory at the location of the address of givenChar as a zero-terminated string. Eg. it would read from the memory until it finds a '\0'. But at the address of givenChar is only space for *one* char which most likely is not zero. This would result in garbage inserted into std::cout (=printed) and eventually lead to an access violation.

So instead you use

char givenChar;
std::cout << (void*) &givenChar;

(void*) is a cast. It converts the char* produced by applying the address-of operator & to the char givenChar into a pointer to void. For a void* the operator

ostream& operator<<(void* val);

gets called which will only insert the numeric value of the given address into the stream instead of trying to print a string that might exist at the address.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • Thank you for that amazing write-up. wow. Wish maybe you could elaborate on, "This would result in garbage inserted into std::cout (=printed) and eventually lead to an access violation." – Michael Rader Oct 19 '18 at 09:01
  • @MichaelRader When `operator<<(std::ostream&, char const*)` tries to interpret the pointer you feed it as a zero terminated string it will not only read `givenChar` and print it, but it will then try to read the char at `&givenChar + 1`, check if it is 0 stop else print it. and again for the char at `&givenChar + 2`, and for `&givenChar + 3` and so on. First thing is that your program doesn't own this memory `operator<<` is going to read so it is undefined behaviour what happens, the other thing is that noone can predict which values there are in the memory after `givenChar` since it hasn't – Swordfish Oct 19 '18 at 09:32
  • @MichaelRader been initialized nor written to before. Verstehste? – Swordfish Oct 19 '18 at 09:33
2

In C++ operators work based on the types of their operands. Here the behavior of the << operator depends on [the type of] its right hand side operand.

For example, if you want to print out an integer with cout << 1, the string 1 will be printed. If on the other hand the operand is a pointer then the output will be in hexadecimal and will have a 0x prefix.

If the operand is a char pointer (&givenChar), the behavior is also different, the operator will print the characters starting from that address until the first zero byte.

If you want to print the address of a character, you need to have a void pointer to achieve that. To have a void pointer, you need to cast the char *: (void *) givenChar.

perreal
  • 94,503
  • 21
  • 155
  • 181