Diferente valor del &array en main() y en función()
Disculpen mi mal inglés primero.
Me encontré con un problema extraño al programar en C++.
“` #include
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;
}
“`
Estaba confundido de que &a en main() y en la función Func() retornaban valores diferentes. Y extrañamente, la diferencia entre ellos siempre es 212.
¿Alguien puede explicar, por favor? Gracias por su ayuda.
P/d: Gracias a todos por sus respuestas. Mi profesor dice que C++ no permite pasar una matriz por valor, porque si la matriz tiene 1 millón de elementos, eso disminuiría mucho el rendimiento solo para copiar todos ellos. Él dice que solo se permite pasar por referencia. Eso es lo que me hizo pensar que esos dos &a deberían ser iguales. Ahora lo entiendo, gracias a todos.
davy.ai
Explicación del problema
En el fragmento de código proporcionado, se declara un arreglo
a
de tamaño 2×3 en la función principal. Luego, este arreglo se pasa como argumento a la funciónFunc
. En ambos lugares, se imprime la dirección de memoria del arreglo utilizando el operador&
y se convierte a entero utilizando(int)
.Ahora, el problema es que las dos direcciones de memoria impresas difieren en 212 a pesar de que ambas apuntan al mismo arreglo en memoria.
Razón del problema
Esto sucede debido a la forma en que se almacenan los arreglos bidimensionales en memoria en C++. Un arreglo bidimensional en C++ es en realidad un bloque contiguo de memoria donde cada fila se almacena una después de la otra. Por lo tanto, para el arreglo
a
dado, la disposición de la memoria se vería así:donde los números representan los elementos del arreglo.
Cuando el arreglo
a
se pasa a la funciónFunc
, se convierte implícitamente en un puntero a su primer elemento, es decir,int*
que apunta a la primera fila del arreglo. Por lo tanto, la dirección de memoria dea
enFunc
es la dirección de la primera fila del arreglo.Por otro lado, en la función principal, la dirección de memoria del arreglo
a
es la dirección del arreglo completo, que incluye ambas filas. Por lo tanto, las direcciones de memoria son diferentes, pero la diferencia entre ellas es exactamente el tamaño de una fila, que son 3enteros
o 12 bytes en la mayoría de los sistemas.Conclusión
En conclusión, las dos direcciones de memoria difieren debido a la forma en que se almacenan los arreglos bidimensionales en memoria en C++. Pasar un arreglo a una función resulta en una conversión implícita a un puntero a su primer elemento y, por lo tanto, la dirección de memoria impresa en la función es la dirección de la primera fila del arreglo.