I'm sorry for my bad English first. I've encountered a strange problem when coding in C .
using namespace std;
void Func(int a[2][3])
{
cout <<(int) &a;
}
int main()
{
int a[2][3] =
{
{1,2,3},
{4,5,6}
};
cout << (int)&a << endl;
Func(a);
return 0;
}
I was confused that &a in main() and in function Func() returned different values. And strangely, the difference between them always is 212. Can anyone explain please? Thank you for your help.
P/s:Thank you all for your answer .My teacher says that C doesn't allow passing an array by value, because if the array has 1 million elements, that would decrease the performance a lot only for copying all of them, so he says only pass by reference is allowed. That's what make me think those two &a should be the same. Now I get it, thank you everyone!
CodePudding user response:
Your function declaration
void Func(int a[2][3])
is completely equivalent and interchangeable with:
void Func(int (*a)[3]).
As you can see, you are passing a pointer to an array of three ints by value. Therefore the address of the local function parameter is different from the address of the variable in main, even if they may hold the same value.
CodePudding user response:
You're passing the a
argument by value, so each function has its own copy of it (of the pointer, not the array data). The constant offset you're seeing comes from the distance between the stack frames of the two functions, and this is constant.
If you change the function to get a reference to the array (void Func(int (&a)[2][3])
you will get the same value in both cases
CodePudding user response:
The parameter and the local variable are distinct objects and since their lifetimes overlap, they must have distinct memory addresses.
CodePudding user response:
Please read about pass by value and pass by references. So what happened here is:
- you initialised an array in
main
function.&a
will refer to the address ofa
. - you passed as a pass by value argument to another function. A copy of a is created to be consumed in
Func
and&a
will refer to the memory location ofa
local toFunc
.
I hope the concept is clear.
CodePudding user response:
Use the following syntax to pass arrays by (const) reference : const int (&a)[2][3]
#include <iostream>
void func(const int (&a)[2][3])
{
for (const auto& row : a)
{
for(const auto& value : row )
{
std::cout << value << " ";
}
std::cout << "\n";
}
}
int main()
{
int a[2][3] =
{
{1,2,3},
{4,5,6}
};
func(a);
return 0;
}
CodePudding user response:
This is because C rules on how pointers and arrays work are a little weird. You're actually taking the address of a pointer to the array, not the actual address of the array. If you want to get the address to the array you need to take the address of the first element instead:
&a[0]
CodePudding user response:
For starters it is a bad idea to cast an address to the type int like
cout << (int)&a << endl;
you could just write
cout << static_cast<void *>( a ) << endl;
or
cout << static_cast<void *>( &a ) << endl;
The both statements will output the same value: the address of the extent of memory occupied by the array.
In this function call
Func(a);
the array designator is implicitly converted to pointer to its first element of the type int( * )[3]
.
The value of the pointer expression is assigned to the local variable (parameter) a of the function Func.
The function parameter of the pointer type a and the array a defined in main occupies different extents of memory.
If to rename the function parameter as for example like
void Func(int b[2][3])
to distinguish it from the array defined in main then you may imagine the function call the following way
Func(a);
//...
void Func( /*int b[2][3] */ )
{
int ( *b )[3] = a;
cout << static_cast<void *>( &b );
}
Pay attention to that the function parameter declared as having the array type int[2][3]
is implicitly adjusted by the compiler to pointer to teh array element type that is int ( * )[3]
.
So as you can see this statement
cout << static_cast<void *>( &b );
outputs the address of the local variable (parameter) b
.
If you want to get the address of the array a within the function Func then you should write
cout << static_cast<void *>( b );
In this case the addresses outputted in main and in the function will coincide because the parameter b
stores the address of the first element of the array a
.