Problem understanding pass by value and pass by reference of arrays and what happens in the memory

V

venkatagmail

I have problem understanding pass by value and pass by reference and
want to how how they are or appear in the memory:

I had to get my basics right again. I create an array and try all
possible ways of passing an array. In the following code, fun1(int
a1[]) - same as fun1(int* a1) - where both are of the type passed by
reference. Inside this function, another pointer a1 is created whose
address &a1 is different from that of the passed array a, which is &a
in the main method. However, the addresses of a[0] and a[1] in the
caller or main function are same as those of the array a1[0] and a1[1]
in the called function fun1(int a1[]). Any modifications to the array
in this function will reflect in the main method. How and where are
these variables created in stack, heap, tables and what happens after
and before calling the function?

Lets look at the other function fun2(int *&a2) where I am trying to
again pass by reference, but this time I do not want to create another
pointer but directly work on the original pointer pointing to the
array. When I pass this array a to this function it returns the
following error which I did not understand

fun2(a); // ERROR: invalid initialization of non-const reference of
//type 'int*&' from a temporary of type 'int*'

however, if I create another pointer int *aPtr = a; and then pass it
as fun2(aPtr); it works fine. Also in this case, I am working directly
with aPtr in both caller(main) and called (fun2) methods. i.e., &aPtr
is same in the caller and called functions, &a2 in fun2(int* &a2),
unlike the previous case, even this is pass by reference. I did not
have time to figure out the problem, so I am posting it here for
discussion and would like to know the details, as to how these
variables are created or assigned in memory.


#include<iostream>
using namespace std;

void fun1(int a1[]) // same as fun(int* p)
{
cout << "In fun(int a1[]) " << "a1 " << a1 << " &a1 " << &a1 << "
&a1[0] " << &a1[0] << endl;
// int a1[] is in a different location (different &a) but has the
// correct addresses of a1[0] and a1[1]
a1[0] = 10;
a1[1] = 20;
}

void fun2(int* &a2)
{
cout << "In fun1(int* &a2) " << " a2 " << a2 << " &a2 " << &a2 << "
&a2[0] " << &a2[0] << endl;
a2[0] = 30;
a2[1] = 50;
}

int main()
{
int a[2] = {0,1};
cout << "Main: a " << a << " &a " << &a << " &a[0] " << &a[0] <<
endl;

//fun2(a); // ERROR: invalid initialization of non-const
reference of
//type 'int*&' from a temporary of type 'int*'
fun1(a);
cout << "After fun(a): " << a[0] << ' ' << a[1] << endl;

int *aPtr = a;
cout << "Passing aPtr whose &aPtr " << &aPtr << " aPtr " << aPtr
<< endl;
fun2(aPtr); // Here it is ok, you can also use it as fun1(aPtr)
cout << "After fun1(aPtr): " << a[0] << ' ' << a[1] << endl;

int cInt = 10;
//int* &cPtr = &cInt; // WRONG:logically wrong as you are trying
to create a
// non-const reference of type int* & from
a
// temporary of type int*
int* cPtr = &cInt; // store the address of cInt in cPtr
int* &cRefPtr = cPtr; // make a reference of the cPtr

}

output:

Main: a 0x22ff80 &a 0x22ff80 &a[0] 0x22ff80
In fun(int a1[]) a1 0x22ff80 &a1 0x22feb0 &a1[0] 0x22ff80
After fun(a): 10 20
Passing aPtr whose &aPtr 0x22ff7c aPtr 0x22ff80
In fun1(int* &a2) a2 0x22ff80 &a2 0x22ff7c &a2[0] 0x22ff80
After fun1(aPtr): 30 50
 
J

Jim Langston

venkatagmail said:
I have problem understanding pass by value and pass by reference and
want to how how they are or appear in the memory:

I had to get my basics right again. I create an array and try all
possible ways of passing an array. In the following code, fun1(int
a1[]) - same as fun1(int* a1) - where both are of the type passed by
reference. Inside this function, another pointer a1 is created whose
address &a1 is different from that of the passed array a, which is &a
in the main method. However, the addresses of a[0] and a[1] in the
caller or main function are same as those of the array a1[0] and a1[1]
in the called function fun1(int a1[]). Any modifications to the array
in this function will reflect in the main method. How and where are
these variables created in stack, heap, tables and what happens after
and before calling the function?

Lets look at the other function fun2(int *&a2) where I am trying to
again pass by reference, but this time I do not want to create another
pointer but directly work on the original pointer pointing to the
array. When I pass this array a to this function it returns the
following error which I did not understand

fun2(a); // ERROR: invalid initialization of non-const reference of
//type 'int*&' from a temporary of type 'int*'

however, if I create another pointer int *aPtr = a; and then pass it
as fun2(aPtr); it works fine. Also in this case, I am working directly
with aPtr in both caller(main) and called (fun2) methods. i.e., &aPtr
is same in the caller and called functions, &a2 in fun2(int* &a2),
unlike the previous case, even this is pass by reference. I did not
have time to figure out the problem, so I am posting it here for
discussion and would like to know the details, as to how these
variables are created or assigned in memory.


#include<iostream>
using namespace std;

void fun1(int a1[]) // same as fun(int* p)
{

a1 is a local variable who's contents will be a pointer that is passed in.
cout << "In fun(int a1[]) " << "a1 " << a1 << " &a1 " << &a1 << "
&a1[0] " << &a1[0] << endl;

Outputting a1 will output the contents of it, which is the pointer passed
in, which points to the array a declared in main.
Ouputting &a1 will output the address of the local pointer which is stored
on the stack/heap.
Outputting &a1[0] will output the address of the first int that a1 points
to, which is the same as a1 itself.

Lets presume a 4 byte int. When this function is called 4 bytes are set
aside to hold the paramater a1 (or sizeof int*). Those 4 bytes can be
anywhere in memory where the heap is (I believe compilers are free to use
anywhere, heap is most common. I may be wrong on if they are free to use
wherever or not. I don't have copy of standard). In your case it is memory
locatoin 0x22feb0 to 0x22feb3. When this function is called and you pass
the parameter of the pointer that pointer is pushed onto the stack. The
function is called. The value is popped off and copied into the location of
the local variable a1 (0x22feb0 to 0x22feb3). These 4 bytes in your case
consist of the pointer value 0x22ff80.

Now, if you look at the address of the variable a1 you will get 0x22f3b3.
If you look at it's contents you will get 0x22ff80. If you dereference it
(look at where the pointer is pointing to) you'll get the values in the
array. Which is why &a1[0] returns the address of the original array.
a1[0] says look at the 0th element of where the pointer is pointing to. &
means get the address of it.

Compilers are free to do somethings diffrent, I'm not aware of what they're
allowed and not allowed to do different, but passing pointers is generally
handled this way.
// int a1[] is in a different location (different &a) but has the
// correct addresses of a1[0] and a1[1]
a1[0] = 10;
a1[1] = 20;
}

void fun2(int* &a2)
{
cout << "In fun1(int* &a2) " << " a2 " << a2 << " &a2 " << &a2 << "
&a2[0] " << &a2[0] << endl;
a2[0] = 30;
a2[1] = 50;
}

int main()
{
int a[2] = {0,1};
cout << "Main: a " << a << " &a " << &a << " &a[0] " << &a[0] <<
endl;

//fun2(a); // ERROR: invalid initialization of non-const
reference of
//type 'int*&' from a temporary of type 'int*'
fun1(a);
cout << "After fun(a): " << a[0] << ' ' << a[1] << endl;

int *aPtr = a;
cout << "Passing aPtr whose &aPtr " << &aPtr << " aPtr " << aPtr
<< endl;
fun2(aPtr); // Here it is ok, you can also use it as fun1(aPtr)
cout << "After fun1(aPtr): " << a[0] << ' ' << a[1] << endl;

int cInt = 10;
//int* &cPtr = &cInt; // WRONG:logically wrong as you are trying
to create a
// non-const reference of type int* & from
a
// temporary of type int*
int* cPtr = &cInt; // store the address of cInt in cPtr
int* &cRefPtr = cPtr; // make a reference of the cPtr

}

output:

Main: a 0x22ff80 &a 0x22ff80 &a[0] 0x22ff80
In fun(int a1[]) a1 0x22ff80 &a1 0x22feb0 &a1[0] 0x22ff80
After fun(a): 10 20
Passing aPtr whose &aPtr 0x22ff7c aPtr 0x22ff80
In fun1(int* &a2) a2 0x22ff80 &a2 0x22ff7c &a2[0] 0x22ff80
After fun1(aPtr): 30 50
 
V

venkatagmail

Thank you, as far as I understand from yours, correct me when I go
wrong.

when I start off with my declaration of an array 'a' in main(), they
are created in the heap?, with a[0] ,a[1] pointing to my first and
second elements of array a. The value of a contains the address of
a[0] using which I use to pass as a pointer to an int to fun1(int
a1[]). Before I call this function, all of my automatic variables move
into stack and the address of the caller function is stored at the top
of the stack to be returned to the operating system I believe?

Once I enter the called method fun1(int a1[]) I have access to the
first location of the array which is a[0] (which is already pushed
into stack??) now stored in a1 (a1 is in a different location in
heap), so once I make modifications to a1[0], am I making
modifications to the original value in stack?? (which I know cannot be
modified directly) or are these modified only after I exit the
function fun1, which however is doubtful as a1[0], a1[1] and a[0],
a[1] point to same address locations. I am confused how the memory
thing takes place in case of pass by value, pass by reference using
pointer and using a reference. This is just the beginning of my
problem in understanding memory assignments. The original problem I
posted above has lot more to ask.
 
B

Barry

venkatagmail said:
I have problem understanding pass by value and pass by reference and
want to how how they are or appear in the memory:

I had to get my basics right again. I create an array and try all
possible ways of passing an array. In the following code, fun1(int
a1[]) - same as fun1(int* a1) - where both are of the type passed by
reference. Inside this function, another pointer a1 is created whose
address &a1 is different from that of the passed array a, which is &a
in the main method. However, the addresses of a[0] and a[1] in the
caller or main function are same as those of the array a1[0] and a1[1]
in the called function fun1(int a1[]). Any modifications to the array
in this function will reflect in the main method. How and where are
these variables created in stack, heap, tables and what happens after
and before calling the function?

Lets look at the other function fun2(int *&a2) where I am trying to
again pass by reference, but this time I do not want to create another
pointer but directly work on the original pointer pointing to the
array. When I pass this array a to this function it returns the
following error which I did not understand

fun2(a); // ERROR: invalid initialization of non-const reference of
//type 'int*&' from a temporary of type 'int*'

a is of array type, which is bound to a fixed address. so you can't
change a to point to another one. when you pass an array as a parameter
for a function, here a decays to type /int* const/, so you can convert
it to /int*&/.
however, if I create another pointer int *aPtr = a; and then pass it

conversion from /int* const/ to /int*/ is allowed, /aPtr/ points to
where /a/ points, but /aPtr/ has no way modify where /a/ points to.
this is just like:

const int S = 100;
int i = S;
as fun2(aPtr); it works fine. Also in this case, I am working directly
with aPtr in both caller(main) and called (fun2) methods. i.e., &aPtr
is same in the caller and called functions, &a2 in fun2(int* &a2),
unlike the previous case, even this is pass by reference. I did not
have time to figure out the problem, so I am posting it here for
discussion and would like to know the details, as to how these
variables are created or assigned in memory.

To understand these, you have learn how to find where the constness lays.

as /aPtr/ is typeof 'int*' not 'int* const', then you can have /aPtr/
point to anywhere of 'int' type, and of cause NOT to 'const int', as we
can modify the content where /aPtr/ points to.
#include<iostream>
using namespace std;

void fun1(int a1[]) // same as fun(int* p)
{
cout << "In fun(int a1[]) " << "a1 " << a1 << " &a1 " << &a1 << "
&a1[0] " << &a1[0] << endl;
// int a1[] is in a different location (different &a) but has the
// correct addresses of a1[0] and a1[1]
a1[0] = 10;
a1[1] = 20;
}

void fun2(int* &a2)
{
cout << "In fun1(int* &a2) " << " a2 " << a2 << " &a2 " << &a2 << "
&a2[0] " << &a2[0] << endl;
a2[0] = 30;
a2[1] = 50;
}

int main()
{
int a[2] = {0,1};
cout << "Main: a " << a << " &a " << &a << " &a[0] " << &a[0] <<
endl;

//fun2(a); // ERROR: invalid initialization of non-const
reference of
//type 'int*&' from a temporary of type 'int*'
fun1(a);
cout << "After fun(a): " << a[0] << ' ' << a[1] << endl;

int *aPtr = a;
cout << "Passing aPtr whose &aPtr " << &aPtr << " aPtr " << aPtr
<< endl;
fun2(aPtr); // Here it is ok, you can also use it as fun1(aPtr)
cout << "After fun1(aPtr): " << a[0] << ' ' << a[1] << endl;

int cInt = 10;
//int* &cPtr = &cInt; // WRONG:logically wrong as you are trying
to create a
// non-const reference of type int* & from
a
// temporary of type int*
int* cPtr = &cInt; // store the address of cInt in cPtr
int* &cRefPtr = cPtr; // make a reference of the cPtr

}

output:

Main: a 0x22ff80 &a 0x22ff80 &a[0] 0x22ff80
In fun(int a1[]) a1 0x22ff80 &a1 0x22feb0 &a1[0] 0x22ff80
After fun(a): 10 20
Passing aPtr whose &aPtr 0x22ff7c aPtr 0x22ff80
In fun1(int* &a2) a2 0x22ff80 &a2 0x22ff7c &a2[0] 0x22ff80
After fun1(aPtr): 30 50
 
V

venkatagmail

"a is of array type, which is bound to a fixed address. so you can't
change a to point to another one. when you pass an array as a
parameter
for a function, here a decays to type /int* const/, so you can convert
it to /int*&/."<<<

Barry, do you suggest that, I can convert array a bound to fixed
address which decays to /int* const/ to type /int*&/ ??

i.e., if I create an array int a[] = {1,2}; it is bound to a fixed
address. If I pass it to a function fun2(int *&a2) it gives me an
error!! Whereas I create another ptr /int* aPtr = a/, I can then pass
it as this can now point to any integer and is not a constant value?
where /a/ points, but /aPtr/ has no way modify where /a/ points to.
this is just like:"<<<

In line with what you said above, you say that I can create a pointer
\int* aPtr = a;\ but you also say there is no way to modify where \a\
points to?? But I can modify the contents of \a\ using the \aPtr\
right or am I getting a wrong message here??

What about the memory contents and how these are allocated for the
three types of passing input arguments fun1(int a1[]) or fun1(int *a1)
and fun2(int *&a2) ?? how different are these in terms how memory is
allocated and assigned?
 
B

Barry

venkatagmail said:
change a to point to another one. when you pass an array as a
parameter
for a function, here a decays to type /int* const/, so you can convert
it to /int*&/."<<<

Barry, do you suggest that, I can convert array a bound to fixed
address which decays to /int* const/ to type /int*&/ ??

i.e., if I create an array int a[] = {1,2}; it is bound to a fixed
address. If I pass it to a function fun2(int *&a2) it gives me an
error!! Whereas I create another ptr /int* aPtr = a/, I can then pass
it as this can now point to any integer and is not a constant value?
where /a/ points, but /aPtr/ has no way modify where /a/ points to.
this is just like:"<<<

In line with what you said above, you say that I can create a pointer
\int* aPtr = a;\ but you also say there is no way to modify where \a\
points to?? But I can modify the contents of \a\ using the \aPtr\

*where* /a/ points to can't be modified,
*what* /a/ points to can be modified.

int* aPtr = a;
then you can modify *what* /a/ points to, /aPtr/ works just like a proxy;

also, you can modify /aPtr/ to point to somewhere else like:

int b[] = {1, 2};
aPtr = b;
now /aPtr/ is a proxy of /b/;
right or am I getting a wrong message here??

What about the memory contents and how these are allocated for the
three types of passing input arguments fun1(int a1[]) or fun1(int *a1)
and fun2(int *&a2) ?? how different are these in terms how memory is
allocated and assigned?

Sorry.
I think my words are not enough to explain these to you.

see this example please.

#include <iostream>
#include <cstddef> // NULL

void print(const int* a, int count)
{
for (int i = 0; i < count; ++i)
std::cout << a << ' ';
std::cout << std::endl;
}

void f1(int a[], int count) // == void f1(int* a, int count)
{
a[0] = 100; // modify WHAT a points to
a = NULL; // a points to NULL (WHERE)
print(a, count);
}

void f2(int* a, int count)
{
a[1] = 200;
a = NULL;
print(a, count);
}

int main()
{
int a[] = {1, 2, 3, 4};
print(a, 4);
f1(a, 4);
f2(a, 4);
print(a, 4);
}
 
B

Barry

Barry said:
venkatagmail said:
"a is of array type, which is bound to a fixed address. so you can't
change a to point to another one. when you pass an array as a
parameter
for a function, here a decays to type /int* const/, so you can convert
it to /int*&/."<<<

Barry, do you suggest that, I can convert array a bound to fixed
address which decays to /int* const/ to type /int*&/ ??

i.e., if I create an array int a[] = {1,2}; it is bound to a fixed
address. If I pass it to a function fun2(int *&a2) it gives me an
error!! Whereas I create another ptr /int* aPtr = a/, I can then pass
it as this can now point to any integer and is not a constant value?
"conversion from /int* const/ to /int*/ is allowed, /aPtr/ points to
where /a/ points, but /aPtr/ has no way modify where /a/ points to.
this is just like:"<<<

In line with what you said above, you say that I can create a pointer
\int* aPtr = a;\ but you also say there is no way to modify where \a\
points to?? But I can modify the contents of \a\ using the \aPtr\

*where* /a/ points to can't be modified,
*what* /a/ points to can be modified.

int* aPtr = a;
then you can modify *what* /a/ points to, /aPtr/ works just like a proxy;

also, you can modify /aPtr/ to point to somewhere else like:

int b[] = {1, 2};
aPtr = b;
now /aPtr/ is a proxy of /b/;
right or am I getting a wrong message here??

What about the memory contents and how these are allocated for the
three types of passing input arguments fun1(int a1[]) or fun1(int *a1)
and fun2(int *&a2) ?? how different are these in terms how memory is
allocated and assigned?

Sorry.
I think my words are not enough to explain these to you.

see this example please.

#include <iostream>
#include <cstddef> // NULL

void print(const int* a, int count)
{
for (int i = 0; i < count; ++i)
std::cout << a << ' ';
std::cout << std::endl;
}

void f1(int a[], int count) // == void f1(int* a, int count)
{
a[0] = 100; // modify WHAT a points to
oops:

a = NULL; // a points to NULL (WHERE)
print(a, count);


print(a, count);
a = NULL;
}

void f2(int* a, int count)
{
a[1] = 200;
a = NULL;
print(a, count);

print(a, count);
a = NULL;
}

int main()
{
int a[] = {1, 2, 3, 4};
print(a, 4);
f1(a, 4);
f2(a, 4);
print(a, 4);
}
 
V

venkatagmail

Thank you Barry for making me realize the problem of const and non-
const reference and pointers. I wished I also understood how the
memory is allocated in detail when calling these different methods.
I have problems understanding linked lists where I pass a head node
pointer by value and by reference. In either case I am able to access
the all the subsequent nodes until the end of the list, delete and
make modifications to them in the called function. I still want to
understand these things in terms of the memory allocation and
deallocation in heap and stack.
 
J

Jim Langston

venkatagmail said:
change a to point to another one. when you pass an array as a
parameter
for a function, here a decays to type /int* const/, so you can convert
it to /int*&/."<<<

Barry, do you suggest that, I can convert array a bound to fixed
address which decays to /int* const/ to type /int*&/ ??

i.e., if I create an array int a[] = {1,2}; it is bound to a fixed
address. If I pass it to a function fun2(int *&a2) it gives me an
error!! Whereas I create another ptr /int* aPtr = a/, I can then pass
it as this can now point to any integer and is not a constant value?
where /a/ points, but /aPtr/ has no way modify where /a/ points to.
this is just like:"<<<

In line with what you said above, you say that I can create a pointer
\int* aPtr = a;\ but you also say there is no way to modify where \a\
points to?? But I can modify the contents of \a\ using the \aPtr\
right or am I getting a wrong message here??

What about the memory contents and how these are allocated for the
three types of passing input arguments fun1(int a1[]) or fun1(int *a1)
and fun2(int *&a2) ?? how different are these in terms how memory is
allocated and assigned?

There is no differnce. In all cases an address is pushed onto the stack and
popped off by the function. It's just how the compiler treates them that is
different.
 
B

Barry

venkatagmail said:
Thank you Barry for making me realize the problem of const and non-
const reference and pointers. I wished I also understood how the
memory is allocated in detail when calling these different methods.
I have problems understanding linked lists where I pass a head node
pointer by value and by reference. In either case I am able to access

pass by reference IIF you create the list inside the function body,
then you assign the "created pointer to root" to the passed in
reference, then the function caller gain the side-effect, the passed in
parameter then points to the created list. after calling the function.

in C, we often use pointer to pointer for this goal.
the all the subsequent nodes until the end of the list, delete and
make modifications to them in the called function. I still want to
understand these things in terms of the memory allocation and
deallocation in heap and stack.

When accessing modifying the list you can only pass in the pointer to
the list only. As you don't change the passed in pointer to point to
another list(actually a node).


I have an idea for you,
You can use a debugger, like Visual C++, then you can see the the object
lays and how. Pay attention to when/what the variable is
assigned/initialized.

on reference, it's special, you can jump to the assembly code.
I was told that VC uses pointer-like stuff to implement it.

http://www.parashift.com/c++-faq-lite/references.html

TC++PL:
"In some cases, the compiler can optimize away a reference so that there
is no object representing that reference at runtime."

Reference is special, remember.


Here is exmaple when reference to pointer is used:

#include <iostream>
#include <cstddef> // NULL

int g_arr[] = {1, 2, 3};

void get_array(int*& arr, int& count)
{
arr = g_arr;
count = 3;
}

void print(const int* a, int count)
{
for (int i = 0; i < count; ++i)
std::cout << a << ' ';
std::cout << std::endl;
}

int main()
{
int count = 0;
int* pi = NULL;
get_array(pi, count);
print(pi, count);
}
 
J

James Kanze


[...]
void fun1(int a1[]) // same as fun(int* p)
{
a1 is a local variable who's contents will be a pointer that is passed in.

And a1 has type int* a, despite the way it is written.
cout << "In fun(int a1[]) " << "a1 " << a1 << " &a1 " << &a1 << "
&a1[0] " << &a1[0] << endl;
Outputting a1 will output the contents of it, which is the pointer passed
in, which points to the array a declared in main.
Ouputting &a1 will output the address of the local pointer which is stored
on the stack/heap.
Outputting &a1[0] will output the address of the first int that a1 points
to, which is the same as a1 itself.
Lets presume a 4 byte int. When this function is called 4
bytes are set aside to hold the paramater a1 (or sizeof int*).
Those 4 bytes can be anywhere in memory where the heap is (I
believe compilers are free to use anywhere, heap is most
common.

I think you mean stack. Except, of course, that in a lot of
cases, function arguments are passed in registers. It's only
when he takes its address that the compiler generates a local
variable (typically on the stack) for it, and copies the
register into that. (Also, while the machines I use do have
four byte int's, int* is 8 bytes on all of them. Not that it
matters.)
I may be wrong on if they are free to use
wherever or not. I don't have copy of standard).

The standard only describes the behavior of legal programs.
(And the only time it speaks of stack or heap are in the library
sections, concerning library classes or functions---where "heap"
has a completely different meaning.) Anything the compiler does
is legal as long as the resulting program has the "observable
behavior" resulting from the behavior described in the standard.
In your case it is memory
locatoin 0x22feb0 to 0x22feb3. When this function is called and you pass
the parameter of the pointer that pointer is pushed onto the stack. The
function is called. The value is popped off and copied into the location of
the local variable a1 (0x22feb0 to 0x22feb3). These 4 bytes in your case
consist of the pointer value 0x22ff80.

If the argument is already on the stack, all the compilers I
know will use it there. The only time it gets copied into a
local variable is when it was passed by register.
 
J

James Kanze

change a to point to another one. when you pass an array as a
parameter
for a function, here a decays to type /int* const/, so you can convert
it to /int*&/."<<<

I don't like the word "decays" here (although I know it is quite
common). It implicitly converts to, in the same way an int will
implicitly convert to a double. The important thing to remember
(here) is that the pointer is a new, temporary object.
Barry, do you suggest that, I can convert array a bound to fixed
address which decays to /int* const/ to type /int*&/ ??

That's not the problem. The types match. The problem is that
you cannot initialize a reference to non-const with a temporary,
and the result of your conversion is a temporary. This is a
separate rule, outside the type system, which applies to the
initialization of a reference.
i.e., if I create an array int a[] = {1,2}; it is bound to a
fixed address. If I pass it to a function fun2(int *&a2) it
gives me an error!! Whereas I create another ptr /int* aPtr =
a/, I can then pass it as this can now point to any integer
and is not a constant value?

Because a named variable is not a temporary. (The standard
actually speaks in terms of rvalues and lvalues, but it comes
out to the same thing here, at least with non class types: a
temporary is an rvalue, i.e. a pure value, without an address.)

[..]
What about the memory contents and how these are allocated for the
three types of passing input arguments fun1(int a1[]) or fun1(int *a1)
and fun2(int *&a2) ?? how different are these in terms how memory is
allocated and assigned?

The first two are identical: "fun1(int* a)". Given a pointer to
an int (whether it is the result of an implicit array to pointer
conversion, or otherwise, makes no difference), the compiler
uses the value of the argument (the rvalue) to initialize the
function argument (which may be in a register, or on the stack).
The third says that you are passing a reference to the pointer,
and that the pointer may be changed via this reference.
Typically, the compiler implements this by passing the address
of the argument---the address of the pointer, here. Since the
result of a conversion is a pure value, the compiler would have
to artificially generate an object (with pointer type) to hold
it, and pass the address of this object. In fact, the standard
forbids this.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top