Cout ≪≪ With Char* Argument Prints String, Not Pointer Value

Why can std::cout print a char[]? [duplicate]

Because of operator<< (basic_ostream<charT,traits>& os, const char* s); (#2 "character sequence" in that list) (slightly more technical list). test decays to a pointer, or char*, which then gets printed as a C-string.

It's the exact same reason cout << "Jeff"; works (instead of printing the address of "Jeff").

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

Overload resolution selects the ostream& operator<<(ostream& o, const char *c); which is used for printing C-style strings. You want the other ostream& operator<<(ostream& o, const void *p); to be selected. You are probably best off with a cast here:

 cout << static_cast<void *>(cptr) << endl;

How does std::cout work with char pointers?

This happens because the compiler checks the type of the argument and calls the overloaded version of the operator that receives that type.

In the C language, strings are implemented as char arrays terminated with the ’\0’ (nul) character, and arrays are referred to using pointers. So, when the argument received is c, the overloaded operator that receives a char* prints the content of the array up to the nul terminator.

When the argument received is *c, this dereferences the pointer to access its data, and since this is a pointer to char, the overloaded operator that receives a char prints it as a single char.

To print the address of the string array, you can cast the char* pointer to void*, like follows:

std::cout << (void*) c << std::endl;

cout char* printing address instead of value

char * is a special case. For any other pointer, unless you have some specialization you implemented yourself, outputting a pointer outputs that pointer, not what it points to.

Getting different output with printf and cout - C++

it's because rawname is defined as a std::string. You need to use

printf("rawname: %s", rawname.c_str());

The reason is that printf with the %s is expecting a null terminated C string in memory. Whereas a std::string stl string isn't exactly raw - it eventually null terminates in your situation, not sure if that's even a guarantee, since the length is internally managed by stl container class.

Edit:

As pointed out in a comment, internally it's guaranteed to be null terminated. So what you're seeing as 'squiggly lines' is an output of all the allocated but not utilized (or initialized) memory in that string up until the null terminator character.

What happens when running (int *)some string

On this statement:

std::cout << (int *)"Home of the jolly bytes";

It is indeed printing the starting address of the characters in the string literal. A string literal is a const char[N] array (in this case, N=24), and an array decays into a pointer to its 1st element.

std::istream does not have any operator<< that accepts an int* pointer, but it does have one that accepts a char* pointer to print a null-terminated string, and one that accepts a void* pointer to print the address being pointed at.

int* is implicitly convertible to void*, so the code is printing the address of the string literal, rather than printing its contents. But, it is unusual to cast a char* pointer to an int* in this situation, void* would make more sense, eg:

std::cout << (const void *)"Home of the jolly bytes";

In any case, on this statement:

std::cout << (char)*(int *)"Home of the jolly bytes";

It is reinterpreting the starting address of the characters as-if it were the starting address of an int instead. Thus, dereferencing that int* pointer will read the 1st 4 characters together as a single int value (assuming char is 8 bits in size, and int is 32 bits in size):

--------------------------------------------------------------------------------------------
| H | o | m | e | | o | f | | t | h | e | | j | o | l | l | y | | b | y | t | e| s |
--------------------------------------------------------------------------------------------
|___|
|
char*

|_______________|
|
int*

Thus, the dereferenced int will consist of these bytes in memory:

        H    o    m    e
*int = 0x48 0x6F 0x6D 0x65

The code is then truncating that int value to a 1-byte char value.

On a little-endian system, that will yield the value of the H character:

        H    o    m    e
*int = 0x48 0x6F 0x6D 0x65
= 0x656D6F48 (decimal 1701670728)
= 0x48 when truncated to char

On a big-endian system, it will yield the value of the e character instead:

        H    o    m    e
*int = 0x48 0x6F 0x6D 0x65
= 0x486F6D65 (decimal 1215262053)
= 0x65 when truncated to char

C++ char* as a function parameter

A string literal is a const char[N] array in read-only memory (where N is the number of characters in the literal, plus 1 for the null terminator, so in your case 11+1=12). You can't point a char* pointer (ie, a pointer to non-const data) at a string literal, as that would allow for the possibility of altering read-only data, which is undefined behavior.

Simply change your pointer type to const char* instead (ie a pointer to const data), eg.

#include <iostream>
using namespace std;

void func(const char *var)
{
cout << var;
}

int main()
{
const char* test = "Hello World";
func(test);
}

Otherwise, as you say you have no control over the function declaration, then if you really want to pass a string literal to a char* pointer, you should copy the characters into a separate writable char[] buffer first, and then point at that instead, eg:

#include <iostream>
using namespace std;

void func(char *var)
{
cout << var;
}

int main()
{
char test[] = "Hello World";
func(test);
}

Or, if you know for sure that the function will never modify the characters, you can just cast off the const-ness using const_cast (though this is highly NOT recommended, I'm including it for completeness), eg:

#include <iostream>
using namespace std;

void func(char *var)
{
cout << var;
}

int main()
{
char* test = const_cast<char*>("Hello World");
func(test);

/* alternatively:
const char* test = "Hello World";
func(const_cast<char*>(test));
*/
}


Related Topics



Leave a reply



Submit