Easy pointer question

Started by
12 comments, last by Ashkan 16 years, 1 month ago
Ashkan:
Not only does this answer my question clearly, but you also helped me to solve a problem in a separate program I had written a few weeks ago. I had a situation much like the first memory allocation function you posted.

From this information I gather that using a reference to a pointer is a "preferred" or "cleaner" way of using a pointer to a pointer method...which makes sense. It does however raise some confusion about pointers being passed to functions.

From what I have learned thus far, pointers are variables that hold a memory address. So if I pass a pointer to a function, I'm just passing a memory address...right? If so then using the new construct would return the memory location of the new data and store it in the pointer. However as you noted when the function returns, the pointer that I passed to the function is still in its original state.

So I'm obviously getting something wrong in my thinking. Do I have the definition of a pointer confused, or is there something "different" happening when the pointer is passed to a function as a parameter?

I do appreciate all the answers I am getting, really am learning quite a bit here! :-)
Advertisement
Yes, you're right in thinking that a pointer is a variable that holds a memory address. Fundamentally, there's no difference between a pointer to an int, a pointer to a float or a pointer to a custom abstract data type such as a linkedlist. They are all just pointers and as such they are only variables holding memory addresses. A memory address on the other hand is just a discrete integral value. The difference is superficial. This difference is enforced in strongly-typed programming languages, either by the compiler (in a statically type-checked language where type checking is performed during compile time, such as C++) or runtime (in a dynamically type-checked language, where type checking is performed during runtime). Actually type-checking goes well beyond pointers and applies to every data type that you're going to use but that's another discussion.

So, back to our discussion, pointers are just variables and variables are passed by value! Passing a variable by value means that the contents of the variable is copied over. So when we write something like this,

void f( int x ) {  ++x;}int main() {  y = 0;  f( y );  return 0;}


The compiler actually generates some code behind your back that copies the contents of y (0 here) into x so it can be accessed by f(). Actually, what's f() is changing at this point is a *copy* of y and not y itself. That's why we need to pass that variable by reference so f() can access the original contents rather than a copy.

So what's this talk about pass-by-reference if all variables are passed by value? There's actually no such thing as passing by reference! Pass-by-reference is *mimiced* by passing a variable that holds the memory address of another variable, but the pointer that's being passed is actually passed by value. So in the following example:

void AllocateMemory( unsigned char* pBuffer ) {  pBuffer = new unsigned char[ 100 ];}


pBuffer is again a variable, this time holding a memory address, and again is passed by value. What is actually passed by reference is the contents of the buffer (which is none in this example, since pBuffer isn't really pointing anywhere useful. It just holds some garbage value, pointing to some unknown memory location).

Can we directly change the contents of the buffer to which pBuffer points to? Yes. Why? Because we know where it resides in memory. Can we change the contents of the variable that holds the memory address of the beginning of that buffer (i.e. pBuffer itself)? No. Why? Let's see another example before answering this.

void f( int* pX ) {  (*pX)++;}int main() {  int y = 0;  f( &y );  return 0;}


In this example, a variable holding memory address of another variable (AKA a pointer) is passed to f(). The pointer itself is a variable and is passed by value as a result, but this level of indirection **mimics* a pass-by-reference.

So back to our first version of AllocateMemory (shown above), why can't we successfully assign the address of the allocated memory to pBuffer? You got it. Because, pBuffer is a variable and as such is passed by value. What we are actually changing in that function is a *copy* of that pointer not the pointer itself. This copy is useful when we want to access the location where it points to because it makes no difference if we're accessing that memory location via the original pointer or a copy of it, but we can't change the pointer itself because it's a copy. What do we need then? Another level of indirection. So not only can we change the contents of that buffer, but we can also change the contents of that pointer. But can we change the contents of that pointer to pointer to unsigned char? No. Because that's a copy. We can change that, but it has no effect on it's original value. If we want to change that we need yet another level of indirection.

Where do references fit in? References are mostly syntactic sugar. I said mostly because references have some minor differences with pointers, but they're implemented just like regular pointer behind our back.

Hope that helps :)
I understand now!

It also makes sense if I go back to my old c++ book that has a lesson on pointers and references. The lessons say that these items allow access to the data without having to make a local copy. What is left out is what is going on with the pointer variable itself, which you explained very well.

Printed, highlighted and thrown in my notes!
Appreciate the help very much! :-)
You're most welcome :)

This topic is closed to new replies.

Advertisement