C, pasando 2 matrices dimensional

No he usado C pura en algunos años, pero parece que no puedo hacer que este caso de uso realmente básico funcione. Aquí está el caso de uso simple en C simple, la situación real está envuelta en la biblioteca HDF, pero primero debo comenzar con esto.

#include  void print_data(float **data, int I, int J) { for(int i=0;i<I;i++) { for(int j=0;j<J;j++) printf("%02.2f\t", data[i][j]); printf("\n"); } } void initialize_data(float **data, int I, int J) { for(int i=0;i<I;i++) for(int j=0;j<J;j++) data[i][j] = i * 6 + j + 1; } int main(int argc, char *argv[]) { float data[4][6]; int I=4; int J=6; initialize_data((float **)data, 4,6); print_data((float **)data, 4, 6); return 0; } 

El progtwig anterior causará una falla y generará una señal EXC_BAD_ACCESS. Salidas GDB:

 Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00007fff5fc0131a 0x0000000100000de6 in initialize_data (data=0x7fff5fbff348, I=4, J=6) at simple.c:16 16 data[i][j] = i * 6 + j + 1; 

Sé que esto es realmente estúpido, simple, pero estoy en el extremo de mi ingenio tratando de entender esta cosa simple. ¿Podría alguien apuntarme en la dirección correcta para esto?

 void print_data(float **data, int I, int J) 

espera una matriz de punteros a (el primer elemento de matrices de) float .

Pero cuando pasas

 float data[4][6]; 

se pasa un puntero a float[6] .

Así que en print_data , un acceso a

 data[i] 

lee los bytes sizeof(float*) en un desplazamiento de i * sizeof(float*) bytes después de la dirección de los data dirección, e interpreta estos bytes como un float* que luego elimina las referencias (después de agregar un desplazamiento adecuado) en los data[i][j] .

Así que cuando pasas tu matriz 2D, algunos valores float se interpretan como punteros y luego se siguen. Eso a menudo conduce a una falla de segmentación.

Usted puede ya sea declarar

 void print_data(float (*data)[6], int I, int J) 

y pase su matriz 2D, o necesita pasar una matriz de punteros,

 float *rows[4]; for(i = 0; i < 4; ++i) { rows[i] = &data[i][0]; } 

y pasar rows . O, la tercera posibilidad es pasar y esperar una matriz plana.

 void initialize_data(float* data, int I, int J) { for(i = 0; i < I; ++i) { for(j = 0; j < J; ++j) { data[i*J + j] = whatever; } } } 

y pase &data[0][0] de main .

Una matriz bidimensional no se evalúa como un puntero a puntero, por lo que necesita usar una matriz de un puntero a matriz en su prototipo:

 void print_data(float data[4][6]); void print_data(float (*data)[6]);