C,传递2维数组

我现在几年没有使用纯C了,但我似乎无法使这个真正基本的用例工作。 这是简单C中的简单用例,实际情况包含在HDF库中,但我需要首先从这开始。

#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; } 

上述程序将导致失败并引发EXC_BAD_ACCESS信号。 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; 

我知道这真的很简单,但是我正试着弄清楚这个简单的事情。 有人能指出我正确的方向吗?

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

期望一个指针数组(数组的第一个元素) float

但是当你通过时

 float data[4][6]; 

你将指针传递给float[6]

所以在print_data ,访问

 data[i] 

在地址data保存之后,在i * sizeof(float*)字节的偏移量处读取sizeof(float*)字节,并将这些字节解释为float* ,然后在data[i][j]解除引用(在添加合适的偏移量之后) data[i][j]

因此,当您传递2D数组时,一些float值将被解释为指针然后跟随。 这通常会导致分段错误。

你可以申报

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

并传递你的2D数组,或者你需要传递一个指针数组,

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

并传递rows 。 或者,第三种可能性是通过并期望一个扁平arrays

 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; } } } 

main传递&data[0][0]

二维数组不被计算为指向指针的指针,因此您需要在原型中使用指向数组的指针数组:

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