Question about pointers from beginner

Hello everybody. I'm a new learner of C++ and have couple questions about pointers:

1) So, in the chapter about pointers there was pointer declared like: -- const char* terry = "hello"; --
It's been said: "In this case, memory space is reserved to contain "hello" and then a pointer to the first character of this memory block is assigned to terry...we imagine that "hello" is stored at the memory locations that start at addresses 1702...It is important to indicate that terry contains the value 1702, and not 'h' nor "hello", although 1702 indeed is the address of both of these."

So, in the following code I don't understand, if the first character of this memory block is assigned to terry, why I have string "hello" in the output(terry is the pointer, as I thought), when I "cout << terry", why I don't have the address of the first character (address of 'h')?

1
2
3
4
5
6
7
#include <iostream.h>
int main()
{
    const char* terry = "hello";
    cout << terry << endl; // results in output "hello"(why it's not address?)
    cout << *terry << endl; // results in output "h" as I expected
}



2) The same situation, but instead of using "const char*" I'm just using "char*". I have a warning from compiler: "String literal converted to char* in initialization". But the program works exactly like the previous one(with "const char*"). Why do I have this warning when I don't use const???

1
2
3
4
5
6
7
#include <iostream.h>
int main()
{
    char* terry = "hello";
    cout << terry << endl; // results in output "hello"
    cout << *terry << endl; // results in output "h"
}


Hope you could help me to understand this.
Thanks
1) This is a little tricky. You are correct in thinking that 'terry' just contains an address here.

The reason "hello" is printed and not the address is because iostream (cout) makes a special case for char and const char pointer to treat them as string data... since that's usually the intent.

For any other kind of pointer... cout will print the address. But for char pointers.. cout will go to that address and print the string data contained there.

If you want to display the address of 'terry' here, you'd have to cast it to some other type of pointer. A generic void* pointer will do. This will not change the variable in any way... but will "trick" iostream into thinking it's not a char pointer, and therefore it will not print the string data, but will just print the address:

 
cout << static_cast<const void*>(terry) << endl;



2) You should never, ever, ever do this. Compilers only really allow this to support legacy code. Properly written code should never do this.

The reason why string literals should always be const is because they are loaded into memory when the program is started up... and the memory they are loaded into may not be writable. And even if it is... multiple pointers may refer to it (if the string data is pooled) and changing the string data may have unintended consequences.

So yeah.. to answer your question.... it works because the compiler is being friendly because it wants to support old code. But really... in a perfect world... the compiler should refuse to compile this.
Last edited on
Thank you very much, Disch!
Now it became much more clear for me. I appreciate your help very much!
I have the following questions though:

1)Is this correct code to display the address of terry (by pointer "pstatic")?

1
2
3
4
5
6
7
8
9
10
#include <iostream.h>
int main()
{
    const char* terry = "hello";
    void * pstatic;
    pstatic=&terry;
    cout << terry << endl; 
    cout << *terry << endl; 
    cout << pstatic << endl;
}


2) Does "pstatic" points to the address of the first character 'h'? If yes, how could I obtain the address of the others characters ('e', 'l', etc).

Thanks.
1)Is this correct code to display the address of terry (by pointer "pstatic")?


Yes and no. Yes it technically does what you are asking here... but no because I don't think you're asking what you really mean to be asking.

Pointers are variables which contain an address.
Your 'terry' pointer contains an address which points to the string data
Your 'pstatic' pointer contains an address which points to your 'terry' pointer.

1
2
3
4
5
6
const char* terry = "hello";
const void* ptrtoterry = &terry;
const void* ptrtoterrysdata = terry

cout << ptrtoterry << endl;
cout << ptrtoterrysdata << endl;


Here... 'ptrtoterry' points to terry. But 'ptrtoterrysdata' will point to the same data the terry points to (the string data).


Maybe this diagram will help:


  ptrtoterry            terry          <stringdata>
===============    ===============    ===============
|   &terry    | -> | &stringdata | -> |  "hello"    |
===============    ===============    ===============
                                            ^
                                            |
                                      ptrtoterrysdata
                                      ===============
                                      | &stringdata |
                                      ===============


Each box represents a variable or buffer. The name of the variable is above the box... and the contents of the variable/buffer are inside the box.


2) Does "pstatic" points to the address of the first character 'h'? If yes, how could I obtain the address of the others characters ('e', 'l', etc).


In your case, no... because you're pointing to the pointer, and not to the string data.
Ok, I think I've got it...
Just to make sure that I understand it correct:

1) "const void* ptrtoterry = &terry" - this is the address of pointer terry (not the address of the string 'hello')

2) "const void* ptrtoterrysdata = terry" - this is the address of the character 'h' (first character of the string 'hello')... (I'm not sure here....)

How should I obtain the address of other characters in the string 'hello'??? As long as "ptrtoterrysdata" is void, I can't just do something like "++ptrtoterrysdata".... Is it possible at all to do that?
Last edited on
Both 1 & 2 are correct.

How should I obtain the address of other characters in the string 'hello'??? As long as "ptrtoterrysdata" is void, I can't just do something like "++ptrtoterrysdata".... Is it possible at all to do that?


Pointer math takes a little explanation....

1
2
3
4
5
6
char buffer[] = "Some data";
char* ptr = buffer;

cout << *ptr;  // prints 'S'
++ptr;  // legal... increments the pointer to point to the next char
cout << *ptr;  // prints 'o' 


So "yes", you can just use ++ and -- or even + and - to adjust a pointer to point to different characters in the string. The catch is that the compiler sort of does some math magic behind the scenes. In this example... 'ptr' is a char pointer... so when you do ++ it increments the pointer by sizeof(char). However... if you have an int pointer... it would be incremented by sizeof(int):

1
2
3
4
5
6
int buffer[] = {15,23};
int* ptr = buffer;

cout << *ptr;  // 15
++ptr;  // increment pointer to point to the next int
cout << *ptr;  // 23 


This is a little different because ++ doesn't add 1 to the pointer like you might expect... it actually adds sizeof(int) to the pointer. If you want to just add 1 to an int pointer... the only way to do it would be to cast the pointer to a different type (like to a char pointer), add it, then cast it back.

So the lesson here is that when you do math on the pointer... the type of pointer matters. The size of the data being pointed to determines how the pointer gets modified.


And since void pointers have no size.... you cannot do any pointer math on a void pointer. So ++ptrtoterrysdata will give you a compiler error because ptrtoterrysdata is a void pointer. However ++terry would work just fine.
Disch,
thanks a lot! It was really helpful!

Topic archived. No new replies allowed.