What is this last address?

I have just a simple question trying to understand correctly pointers. I understand the first and the second output which work as expected, but the last one is more or less like the first - just with a little shift. What is means? This is the txt string address ?

1
2
3
4
5
6
string txt = "Simple Test";
string* p_txt = &txt;

cout << p_txt << endl;
cout << *p_txt << endl;
cout << &p_txt << endl;



010FFAC4
Simple Test
010FFAB8
Last edited on
&p_txt is the address of the pointer.
So :
The first one is the address of the txt string,
The second one is the value which I get using my pointer,
And the third one is the address of the pointer itself.

Why independently of txt string length, I have always 12 bits as shift?

Confusing :/
Last edited on
Imagine memory as small boxes that values can be put in...

 txt                     p_txt
┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─
│S i m p l e   T e s t ◦│F A C 4│
┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─
 ↑                       ↑
 F                       F
 A  ←the address         A
 C                       B
 4                       8

The first one shows the value that p_txt holds (that is the address of txt)
The second one dereferences (goes to the address held in p_txt) and retrieves what is there.
The third is the address of p_txt itself.

Each box is a byte, so it is 12 bytes different (11 characters and a null terminator).
Last edited on
Why independently of txt string length, I have always 12 bits as shift?

You allocate two variables from stack: a std::string and a pointer. They are probably consecutive in memory.

You ask, why the size of std::string object is 12 bytes (not bits)?

The size of std::string is decided by the Standard Library implementation. Some have 12 bytes, some don't.
Different compiler and/or platform, or just different options of compiler can change that size.

Lets make a simple string type:
1
2
3
4
5
6
class MyString {
  char* data;
  size_t size;
public:
  // interface
};

The MyString contains a pointer and an integer. Sum of sizes of those types (and perhaps some padding) is the size of MyString. It will not change even if 'data' points to (dynamically allocated) array that stores all text of Wikipedia.

The std::string most likely dynamically allocates memory for storing the text, and the std::string object itself needs space for a pointer.
std::string uses what's called Small Buffer Optimisation which means that it allocates a small buffer on the stack which is used if the size of the stored text is not greater than this size. The size of this buffer is implementation/x64/x86 etc specific.

Often this buffer is unioned with the memory pointer if the size of the stored text is greater than the buffer size.
Amazing explanations. Now I understand. Thank you everyone for your kind help. I really appreciate ++

After your explanations, I did some new test so as to go deeper. I found a little thing which is really weird - and I need again some explanation. Please take a look at the last line :

1
2
3
4
5
6
7
8
9
string txt = "Just a long string as a test";
string* p_txt = &txt;

cout << "Address stored in the pointer : " << p_txt << endl; // ok
cout << "Value which the pointer reads : " << *p_txt << endl; // ok
cout << "Address of the pointer itself : " << &p_txt << endl; // ok

*p_txt = "A tiny modification using the pointer"; // ok
cout << "Value which the pointer reads : " << **&p_txt << endl; // !!! 


What this last line does exactly?


010FFAC4
Just a long string as a test
010FFAB8
A tiny modification using the pointer


**&*&*&*&*&*&*&*&*&*&*&*&*&*&*&p_txt works too :)
Last edited on
**&p_txt is same as *(*(&p_txt))

The &p_txt returns address of a pointer. That is effectively a pointer to pointer.

We could store that in a named variable: string** pp_txt = &p_txt;

Dereferencing a pointer returns the pointed to object.
Both *pp_txt and *(&p_txt) return p_txt.
Both *p_txt and *(*(&p_txt)) return txt.
Clever. Thanks ++
Topic archived. No new replies allowed.