I\'m fresh out of college and have been working in C++ for some time now. I understand all the basics of C++ and use them, but I\'m having a hard time grasping more advance
Understanding Pointers in C/C++
Before one can understand how pointers work, it is necessary to understand how variables are stored and accessed in programs. Every variable has 2 parts to it - (1) the memory address where the data is stored and (2) the value of the data stored.
The memory address is often referred to as the lvalue of a variable, and the value of the data stored is referred to as the rvalue (l and r meaning left and right).
Consider the statement:
int x = 10;
Internally, the program associates a memory address with the variable x. In this case, let's assume that the program assigns x to reside at the address 1001 (not a realistic address, but chosen for simplicity). Therefore, the lvalue (memory address) of x is 1001, and the rvalue (data value) of x is 10.
The rvalue is accessed by simply using the variable “x”. In order to access the lvalue, the “address of” operator (‘&’) is needed. The expression ‘&x’ is read as "the address of x".
Expression Value
----------------------------------
x 10
&x 1001
The value stored in x can be changed at any time (e.g. x = 20), but the address of x (&x) can never be changed.
A pointer is simply a variable that can be used to modify another variable. It does this by having a memory address for its rvalue. That is, it points to another location in memory.
Creating a pointer to “x” is done as follows:
int* xptr = &x;
The “int*” tells the compiler that we are creating a pointer to an integer value. The “= &x” part tells the compiler that we are assigning the address of x to the rvalue of xptr. Thus, we are telling the compiler that xptr “points to” x.
Assuming that xptr is assigned to a memory address of 1002, then the program’s memory might look like this:
Variable lvalue rvalue
--------------------------------------------
x 1001 10
xptr 1002 1001
The next piece of the puzzle is the "indirection operator" (‘*’), which is used as follows:
int y = *xptr;
The indirection operator tells the program to interpret the rvalue of xptr as a memory address rather than a data value. That is, the program looks for the data value (10) stored at the address provided by xptr (1001).
Putting it all together:
Expression Value
--------------------------------------------
x 10
&x 1001
xptr 1001
&xptr 1002
*xptr 10
Now that the concepts have been explained, here is some code to demonstrate the power of pointers:
int x = 10;
int *xptr = &x;
printf("x = %d\n", x);
printf("&x = %d\n", &x);
printf("xptr = %d\n", xptr);
printf("*xptr = %d\n", *xptr);
*xptr = 20;
printf("x = %d\n", x);
printf("*xptr = %d\n", *xptr);
For output you would see (Note: the memory address will be different each time):
x = 10
&x = 3537176
xptr = 3537176
*xptr = 10
x = 20
*xptr = 20
Notice how assigning a value to ‘*xptr’ changed the value of ‘x’. This is because ‘*xptr’ and ‘x’ refer to the same location in memory, as evidenced by ‘&x’ and ‘xptr’ having the same value.
We were just discussing some of the aspects of C++ and OO at lunch, someone (a great engineer actually) was saying that unless you have a really strong programming background before you learn C++, it will literally ruin you.
I highly recommend learning another language first, then shifting to C++ when you need it. It's not like there is anything great about pointers, they are simply a vestigial piece left over from when it was difficult for a compiler convert operations to assembly efficiently without them.
These days if a compiler can't optimize an array operation better then you can using pointers, your compiler is broken.
Please don't get me wrong, I'm not saying C++ is horrible or anything and don't want to start an advocacy discussion, I've used it and use it occasionally now, I'm just recommending you start with something else.
It's really NOT like learning to drive a manual car then easily being able to apply that to an automatic, it's more like learning to drive on one of those huge construction cranes then assuming that will apply when you start to drive a car--then you find yourself driving your car down the middle of the street at 5mph with your emergency lights on.
[edit] reviewing that last paragraph--I think that may have been my most accurate analogy ever!
To better understand pointers, I think, it may be useful to look at how the assembly language works with pointers. The concept of pointers is really one of the fundamental parts of the assembly language and x86 processor instruction architecture. Maybe it'll kind of let you fell like pointers are a natural part of a program.
As to classes, aside from the OO paradigm I think it may be interesting to look at classes from a low-level binary perspective. They aren't that complex in this respect on the basic level.
You may read Inside the C++ Object Model if you want to get a better understanding of what is underneath C++ object model.
From lassevek's response to a similar question on SO:
Pointers is a concept that for many can be confusing at first, in particular when it comes to copying pointer values around and still referencing the same memory block.
I've found that the best analogy is to consider the pointer as a piece of paper with a house address on it, and the memory block it references as the actual house. All sorts of operations can thus be easily explained:
- Copy pointer value, just write the address on a new piece of paper
- Linked lists, piece of paper at the house with the address of the next house on it
- Freeing the memory, demolish the house and erase the address
- Memory leak, you lose the piece of paper and cannot find the house
- Freeing the memory but keeping a (now invalid) reference, demolish the house, erase one of the pieces of paper but have another piece of paper with the old address on it, when you go to the address, you won't find a house, but you might find something that resembles the ruins of one
- Buffer overrun, you move more stuff into the house than you can possibly fit, spilling into the neighbours house
One of the things that really helped me understand these concepts is to learn UML - the Unified Modeling Language. Seeing concepts of object-oriented design in a graphical format really helped me learn what they mean. Sometimes trying to understand these concepts purely by looking at what source code implements them can be difficult to comprehend.
Seeing object-oriented paradigms like inheritance in graphical form is a very powerful way to grasp the concept.
Martin Fowler's UML Distilled is a good, brief introduction.
Did you read Bjarne Stroustrup's The C++ Programming Language? He created C++.
The C++ FAQ Lite is also good.