Perhaps this is a digression, but there are some misunderstandings in
this blog post about the memory model in his C++ example. Since the
author goes to lengths to be precise and exact in terminology and his
explanations, it would be good to clarify some things.
In the above, the variable some_guy refers to a location in
memory, and the value 'Fred' is inserted in that location (indeed,
we can take the address of some_guy to determine the portion of
memory to which it refers). Later, the contents of the memory
location referred to by some_guy are changed to 'George'. The
previous value no longer exists; it was overwritten. This likely
matches your intuitive understanding (even if you don't program in
C++).
There are several incorrect statements here.
A. "the variable some_guy refers to a location in memory, and the
value 'Fred' is inserted in that location"
Not true. The variable some_guy refers to a location in memory, but
that location contains a pointer to a region of memory with the
value "Fred". More on this in a bit.
B. "indeed, we can take the address of some_guy to determine the portion
of memory to which it refers".
Again, not true in the way the author probably intended. The
address of 'some_guy' will be the address on the stack where the
variable is located. The value at that address on the stack will be
a pointer to a separate region of memory containing "Fred".
C. "Later, the contents of the memory location referred to by some_guy
are changed to 'George'."
To be precise, the contents of the memory location referred to by
some_guy are changed to a new pointer to a different region of
memory containing "George".
D. "the previous value no longer exists; it was overwritten."
The values "Fred" and "George" exist through the entire lifetime
of the program. They are string constants, which are compiled in
to the data section of the program binary. The author is correct on
one point: the value of 'some_guy' is overwritten during the
reassignment. However, the value in this case is simply a pointer,
not a string.
We can verify my claims experimentally. On my system (Ubuntu 11.04
32-bit, g++ 4.5.2), I wrote the following test program:
//a.cpp
#include <string>
using namespace std;
int main()
{
string some_guy = "Fred";
some_guy = "George";
return 0;
}
Compile like this:
$ g++ -O0 a.cpp -o a
Now, we can disassemble the "main" function to see exactly what is
going on in the executable:
0x4(%esp) is the address on the stack of our 'some_guy' variable. We
are moving an "immediate" (constant) value into that location. What
does that immediate refer to? Again, let's find out experimentally:
$ objdump -s -j .rodata a
a: file format elf32-i386
Contents of section .rodata:
8048778 03000000 01000200 46726564 0047656f ........Fred.Geo
8048788 72676500 00000000 rge.....
Notice that the address of "Fred" is 0x8048778 + 8 = 0x8048780, which
is exactly the immediate value from the disassembled main function.
This means that our variable "some_guy" really is a pointer, and
nothing more. The strings "Fred" and "George" are statically allocated
in the data section of the binary, meaning they stick around
indefinitely.
Comments
Perhaps this is a digression, but there are some misunderstandings in this blog post about the memory model in his C++ example. Since the author goes to lengths to be precise and exact in terminology and his explanations, it would be good to clarify some things.
For the example code C++ given:
Here is the author's explanation: There are several incorrect statements here.A. "the variable some_guy refers to a location in memory, and the value 'Fred' is inserted in that location" Not true. The variable some_guy refers to a location in memory, but that location contains a pointer to a region of memory with the value "Fred". More on this in a bit.
B. "indeed, we can take the address of some_guy to determine the portion of memory to which it refers". Again, not true in the way the author probably intended. The address of 'some_guy' will be the address on the stack where the variable is located. The value at that address on the stack will be a pointer to a separate region of memory containing "Fred".
C. "Later, the contents of the memory location referred to by some_guy are changed to 'George'." To be precise, the contents of the memory location referred to by some_guy are changed to a new pointer to a different region of memory containing "George".
D. "the previous value no longer exists; it was overwritten." The values "Fred" and "George" exist through the entire lifetime of the program. They are string constants, which are compiled in to the data section of the program binary. The author is correct on one point: the value of 'some_guy' is overwritten during the reassignment. However, the value in this case is simply a pointer, not a string.
We can verify my claims experimentally. On my system (Ubuntu 11.04 32-bit, g++ 4.5.2), I wrote the following test program:
Compile like this: $ g++ -O0 a.cpp -o aNow, we can disassemble the "main" function to see exactly what is going on in the executable:
In this case, we are interested in the following two lines: and 0x4(%esp) is the address on the stack of our 'some_guy' variable. We are moving an "immediate" (constant) value into that location. What does that immediate refer to? Again, let's find out experimentally: Notice that the address of "Fred" is 0x8048778 + 8 = 0x8048780, which is exactly the immediate value from the disassembled main function.This means that our variable "some_guy" really is a pointer, and nothing more. The strings "Fred" and "George" are statically allocated in the data section of the binary, meaning they stick around indefinitely.