const char pointer logic


string a = "something funny";

const char * b = "";
b = a.c_str(); //The output is "something funny"

What is happening here? I'm used to think that a " char* " holds an adress(&). It doesn't look like it does it here.

Then, this part below.

b = a.c_str() // Here it looks like the pointer itself is equal to the "content", instead of being equal to an pointer/adress(&) to the content.
std::string declares its c_str() member like this..
const char* c_str() const;

everything looks correct :)

Last edited on
string a = "something funny";

const char * b = "";
b = a.c_str(); //The output is "something funny"


What output? That code doesn't output anything.

b = a.c_str() // Here it looks like the pointer itself is equal to the "content", instead of being equal to an pointer/adress(&) to the content.

c_str() returns a const char*. b is a char*. I don't see what you find odd here.
Last edited on
You aren't being very clear in your question, but I assume you're trying to print b.

std::ostream& operator<<(std::ostream&, const char*) is overloaded to interpret the const char* as a null-terminated c-style string.

It's in a similar fashion to printf("%s", my_c_str);.
Last edited on
"" is const.
b is not const.
b is a normal pointer to a string of const chars (you can't say b[0] = 'x') here.

I believe you are reading the code as if it were

char * const c = "";
string s = "blah blah";
c = s.c_str();
cout << c << endl;

^^^ will not compile, attempting to mess with constant c

Does that make sense? There is a rule of left (I can't recall the exact name) for understanding weird declarations, you might find that with a little google searching...

I have apparently mixed up the return values. But Repeator you made it a bit clearer to me. Thank you all.

But the quotes ( "" ), what do they do in the following example?

const char * b = "";

Do they create a string and then return an address? And also, why does it need to be constant?
But the quotes ( "" ), what do they do in the following example?


"" denotes the string literal that is an empty string.

https://www.tutorialspoint.com/cplusplus/cpp_constants_literals.htm

const char * b = ""; declares a pointer to a const char, and initialises it to the address of that empty string literal.

And also, why does it need to be constant?

Literals are held in reserved areas of memory, that are not supposed to be changed by code. Changing the value held at the address storing that literal, would mean that every time any other code tried to use that literal, it would find the wrong value in that memory. So it is illegal to modify that memory, and hence illegal to treat it as not constant.


Last edited on

This made sense. Thanks Mikey
You're welcome. Glad I could help!

The same subject, so I'll continue here instead of creating a new thread.


char myArray[3] = {'h','i','\0'};
char * ptr1 = myArray; // I dont know what is happening here, because i'm not using "&" before "myArray" when I'm setting the pointer equal to it. So I guess something is happening automatically. But what?

cout << ptr1; // This returns the memory location/adress in the other example below, but why does it return all characters in this example? What is happening under the hood?



int myInt = 2;
int * ptr2 = &myInt;

cout << ptr2; // Here I have to use "*" to get the value that the pointer is pointing to, if I dont use it I get the memory adress instead.


So its confusing because if I cout the pointername without "*", it gives different results depending on what type of pointer it is. I need to now the reason behind this so I get a better understanding of how pointers works.


My understanding was that, either you use the pointername to get the adress that the pointer is pointing to, or use "*" before the pointername to get the value that the pointer is pointing to. Apparently, this doesn't apply to char arrays.
<< is an operator. You can think of it like a function. When you call the function with a char-pointer, the function you call is programmed to output the character(s) being pointed at.

When you call the function with an int-pointer, a different function is called. That function is programmed to output the value of the pointer (i.e. the address of the int).

You get different results because you're calling different functions.
... this is for the pureists out there ;)

the compiler converts some things (arrays, functions, others) into pointers for you. the name of an array is converted into a pointer as a shortcut / handy feature. (this is true for ALL arrays of ANY type, it is NOT a special thing for char).

char *pt1 = myarray;
is a shortcut for and the same as
char *pt1 = &(myarray[0]);

cout knows that char arrays are "strings". This is built into the cout function so you don't have to write a for-loop to print a string one char at a time.

cout << ptr1 is the same as cout << myarray and will print the string. If you want to see the address you must do it explicitly:

cout << (int)(ptr) should do it.

cout is NOT wired to do that for anything except strings. It does what you expect for every other type, which requires you to explicitly code what you are printing (the value or the address).

it is confusing until you understand that arrays or pointers of characters are left over from old language where that WAS a string so there are many language features that support the use of those AS strings which give unusual or 'one off special case' treatment for them. You should use c++ string now, (string s = "text"), but the language still supports all the old stuff and you are seeing that here.

Your understanding seems to be correct apart from this feature of the language.
Last edited on
I don't like all these automizations/"special case changes". I want to program with the same logic every time it has to do with the SAME thing, for example as pointers.

Its like if you're dealing with a white person you get some help on the way. But if it's a black person you have to deal with it yourself. Or the other way around. It should be the same for all cases. I rather deal with it myself as long as it keeps its logic/psychology. Otherwise its just a languge with some random commands rather then a logical structure behind it. (That was what i was hoping for when I started with c++)

Maybe there is a better language suited for me? Or maybe I can use c++ in a different way?
You're the one calling existing functions and operators. It's up to you to know what they do.

If you don't like what a function or operator does, don't use it.
We just had a thread like this a bit ago, where people were talking about "%s" vs "%p", but how it's implicit in C++'s cout as opposed to C.
This is necessary in order to make constructs like std::cout << "Hello, world!"; possible. Otherwise, it would print out the memory address of "Hello, world!", which no one would want. http://www.cplusplus.com/forum/general/242111/#msg1075384

This really isn't as big of a deal as you're making it. You usually never, ever need to print a memory address. They are an implementation detail, it doesn't matter if the value is 42 or 1324817. The only thing that should matter is whether a pointer is null or not.

If you want to be explicit about what you want to interpret a pointer as, use printf. Otherwise, write your own wrapper or cast it to void*.

In fact, I prefer the explicit cast (even if it's a int*), because it makes your intention clear that you're doing the edge case of printing out a memory address.
Last edited on
Maybe there is a better language suited for me? Or maybe I can use c++ in a different way?
------------------------------
all languages have some weirdness that you just have to learn and deal with. This will be the difference between being a master of the language vs being a grunt. Grunt coding... sure, most of us can read nearly any language and with a web search and an existing program, hack on the code to fix it or modify it to do something else etc. But a true master of (whatever) language can look at the code and say "this is the wrong approach, whoever wrote this didn't know this language well" and re-write it into better/faster/more correct/ more readable/more 'standard' etc code.

But the answer is #2, I believe.
In truth, modern c++ does not rely on a lot of hands-on pointer manipulations nor old C style strings and looking at addresses is only useful when debugging (specifically, debugging the aforementioned pointer code that you shouldn't be writing a lot of!). You should be learning to use std::string and <vector> and similar containers which do all the pointer magic for you. And odds are you will graduate to writing a lot of GUI code, not dropping cout statements everywhere, so how cout behaves is also of less than huge importance in the grand scheme than you might think. There are still details you must learn to do higher level coding, but it is MUCH more consistent, and you will make your own objects consistent as well. Other peoples code/libraries, you have to roll with it if they have weirdness, and most do :( and that is true for all languages.

Maybe there is a better language suited for me?

Have a look at Java. It only has one String class and no pointers.
Topic archived. No new replies allowed.