This small program exhibits the problem that I am having.
I have a pointer to a struct, which I want to initilise (new) in a function.
It compiles okay - and runs, but crashes at the 'cout'. Running in Debug you can see that after the call to tryToInitialiseArray, myStruct_ is still NULL.
I guess this is because the myStruct_ is being passed by copy (not as a pointer or reference) - but I don't understand why.
Can anybody help?
(I have also tried it without the 'struct" in the function definition, with the same results.
Now, however, the copy of the address doesn't obscure the underlying pointer which the caller is attempted to have allocated for it.
Using the reference to a pointer approach, the same "pointer to a pointer" is passed, but the compiler offers the added convenience of leaving the original form of the function intact, as the reference is "automatically de-referenced" when it is used (that' the nature of a reference).
In either case, this makes the function act upon the caller's pointer, not a copy of that pointer.
Let me underscore the point which gets students' heads spinning out of control.
A copy of an address is not a pointer, it's a pointer TO a pointer.
A copy of a pointer is just that, a copy.
consider...
void func( int );
a = 5;
func( a );
What happens here? A copy of a is pushed on the stack. Whatever func does to a inside, the caller's "original" for a is unchanged.
void func( int & );
func( a );
Now what happens? A copy of the ADDRESS of a is pushed on the stack. Inside func, this address is a pointer to an integer (the original integer in the caller's code), and is automatically de-referenced when it is used. Now, all changes made inside func are witnessed in a after func executes, because the function was directed to work upon the integer at that address.
void func( int *);
func( &a );
This is similar to the reference above, but it will not be de-referenced automatically - inside func the integer pointer is exposed raw, so it will have to be dereferenced as it is used, but no matter, what it will be doing is acting upon a copy of the address of a, just as the reference version did, and so the caller's a will be modified by func.
void func( object * );
object *b;
func( b );
This is where students get off track. This looks like the example func( int *), so the changes to b ought to be seen in the caller, right? True, it is. But that's a change to the object b.....
What tryToInitialiseArray was attempting to do was to allocate memory. In that case, the caller is expected to see the changes made to the pointer b, not just to the object to which it points. If instead you had....
myStruct_ = new myStruct[3];
Then....
func( myStruct_ );
would work if and only if the function were something like...
Note that this function is not allocating memory. That's done in the calling code.
We are expecting to modify the structure, not the pointer. In this configuration, the allocated myStruct_ is a pointer to an instance. The call to tryToInitialiseArray is pushing a copy of that pointer. The function is acting upon the copy, modifying the structure.
When the function returns, the calling code is looking and using it's original myStruct_. The function never attempted to change it (it didn't need to), and it makes no difference if access modified the instance through the original pointer or a copy of it - the memory location is the same.
It's important to visualize the difference between a function modifying what a pointer points TO, or a modification to the pointer ITSELF.
For the latter, you have to push a copy of the ADDRESS of that pointer - or, put another way, the ADDRESS of the ADDRESS of the instance.
For the former, you only need a copy of the pointer, a copy of the address of the instance.
Last edited by JVene; July 26th, 2009 at 10:53 AM.
If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).
void increment(int i)
{
i++;
}
int main()
{
int val = 0;
increment(val);
cout << val;
}
Naturally, val is not incremented because the function is working on a copy rather than the original, and 0 is printed. Some people get confused when they start dealing with pointers since they can modify the target of the pointer, but the same principal applies to the pointer itself.
Bookmarks