que - Diferencia entre puntero a puntero y puntero a 2d matriz
punteros y arreglos en c (2)
Si tengo un 2d array B definido como:
int B[2][3] = {{1,3,5},{2,4,6}};
¿
int **p = B
igual aint (*p)[3] = B
?int **f = B; printf("%d ",*f+1);
da
5
como salida mientrasprintf("%d ",*f)
da 1 como respuesta. ¿Por qué está sucediendo eso?printf("%d ",**f);
devuelve una falla de segmentación! ¿Por qué?
No.
int **p = B;
es un error (Ambos, un error de compilación y un error lógico). Unint **
debe apuntar a unint *
. Sin embargo, no hayint *
almacenado enB
B
es un grupo deint
contiguas sin punteros implicados.int **f = B;
debe dar un error de compilación. El comportamiento de cualquier ejecutable generado como resultado está completamente indefinido.Ver 2.
Explicar por qué podría estar viendo 1
y 5
. (El estándar C no define esto, pero los toros de compilación están adelante de todos modos). Probablemente su compilador trate la línea como
int **f = (int **)B;
Luego, la expresión *f
leerá los bytes del almacenamiento de B
(que en realidad contienen int
s) y pretenderá que esos son los bytes que componen una representación de puntero. Este es otro comportamiento indefinido (violación de reglas de alias estrictos). Probablemente el resultado de esto es que *f
es un puntero a la dirección 0x00000001
.
Luego imprime un puntero usando %d
, causando un comportamiento indefinido adicional. Verá 1
porque su sistema usa el mismo método para pasar int
a printf
que para pasar int *
.
Cuando agrega 1 a (int *)0x00000001
, obtiene (int *)0x00000005
, porque incrementar un puntero significa apuntar al siguiente elemento de ese tipo.
Cuando desreferencia este puntero, causa un segfault porque esa dirección está fuera de su espacio de direcciones válido.
1) ¿Es int **p = b
igual que int (*p)[3] = b
? - No. int **p = b
es un error.
Porque aquí int **p
es un puntero a puntero a un entero, pero int (*p)[3]
es un puntero a una matriz de 3 enteros!
2) int **f = B;
Es un error, mayo da como resultado un comportamiento Indefinido!
3) printf("%d ",**f);
- Es lo mismo que (2). int **f = B;
es un error, por lo que el comportamiento indefinido!
NOTA: Para evitar este tipo de error, habilite algunos indicadores de advertencia en la opción del compilador y ¡pruebe!