2012-12-06 128 views
1

我幾年來沒有用過純C了,但是我似乎無法做出這個真正基本的用例工作。下面是簡單C中的簡單用例,實際情況包含在HDF庫中,但我首先需要從此開始。C,傳遞2維數組

#include <stdio.h> 

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; 

我知道這真的很愚蠢簡單,但我在我的智慧'結束試圖找出這個簡單的事情。有人能爲我指出正確的方向嗎?

+0

此代碼沒有二維數組,這是一個指針指針。刪除main(float **)強制轉換並啓用所有編譯器警告。 [相關問題](http://stackoverflow.com/questions/12462615/how-do-i-correctly-set-up-access-and-free-a-multidimensional-array-in-c)。 – Lundin

+1

二維數組與指針指針(**)不同。數組的名稱'data'仍然只是一個指針(基地址)。這可能是EXC_BAD_ACCESS的根源。 –

+0

-1。關於同一主題有許多問題,甚至第一個問題也不應該被問到(因爲任何優秀的C教程都會清除這個問題。) – 2012-12-06 18:42:36

回答

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

預計指針數組(數組的第一個元素)float

但是,當你通過

float data[4][6]; 

你傳遞一個指針float[6]

所以在print_data,以

data[i] 

接入在i * sizeof(float*)字節什麼解決data保持後的偏移sizeof(float*)字節讀取和解釋這些字節作爲float*它然後解除引用(添加合適的偏移後)在data[i][j]

所以當你傳遞你的二維數組時,一些float值被解釋爲指針,然後跟着。這通常會導致分段錯誤。

您可以聲明

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

,並通過你的二維數組,或者你需要傳遞一個指針數組,

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

,並通過rows。或者,第三可能性是通過,並期待一個扁平陣列

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]

+0

有沒有正確的方法來處理這樣的浮動矩陣? – lukecampbell

+1

要麼有函數需要一個指向數組的指針,但是這需要在定義函數時維度是固定的,或者將指針數組傳遞到二維數組中,然後遵循這些指針(同時在答案中有一個示例) 。 –

+0

好的,謝謝,我明白了 - 接受我的讚揚並檢查。 – lukecampbell

1

一個雙dimensionnal陣列不計算爲一個指針的指針,所以你需要在你的原型使用的一個指針數組的數組:

​​
+0

如果尺寸無界,那麼函數不知道尺寸的大小會怎樣。 – lukecampbell

+0

@lukecampbell'print_data(float * data)'在這種情況下。當作爲參數發佈時,維度只是語法糖。 – Lundin

+0

@lukecampbell:您還需要傳遞大小,也就是'print_data(float * data,size_t size)' –