2014-05-17 79 views
0

我試着調試下面的代碼,並且出現「訪問衝突」錯誤。我不明白爲什麼第二個循環在訪問第二行元素時失敗,而第一個循環能夠訪問所有元素。2D陣列訪問衝突

我搞砸了*,&[],但無法弄清楚。

謝謝。

#include <iostream> 

void a(const int* data, unsigned int nElements, unsigned int nColumns) { 

    for (unsigned int i = 0; i < nElements; ++i) 
     std::cout << data[i]; 

    for (unsigned int i = 0; i < nElements/nColumns; ++i) 
     for (unsigned int j = 0; j < nColumns; ++j) 
      std::cout << (&data)[i][j]; 
} 

int main() { 
    int arr[2][5] = { 
     { 0, 1, 2, 3, 4 }, 
     { 5, 6, 7, 8, 9 } 
    }; 

    a(*arr, 2 * 5, 5); 

    return 0; 
} 
+0

你能解釋一下你想要做的更多嗎?有點不清楚。 – Ben

+0

真正的問題在這裏:(&data)[i]。由於數據是參數中的單個元素,因此&data是指向單個元素的指針。這意味着i> 0是一個問題。多維數組實際上是一塊內存,當你在多維數組上進行[i] [j]操作時,編譯器將其與[i] [j]中的指針數組區別開來。多維數組上的[i] [j]與[i * numcolumns + j]相同。 – thang

回答

0

你失去了所有類型的信息,一旦你在你的a功能,所以你不能指望下標運算符的工作,你不說什麼數組的大小。在參數中指定的上市規模和下標將工作:

void a(int const (&data)[2][5]) { 
    for (auto const& row : data) 
    for (auto i : row) 
     ::std::cout << i << " "; 
    ::std::cout << ::std::endl; 
} 

然後,您可以甚至發瘋,改變原型:

template <size_t R, size_t C> 
void a(int const (&data)[R][C]) { 

所以它適用於所有二維數組。

+0

在傳遞參數 - 'a(arr,2 * 5,5);'並在參數中指定大小時刪除星號,同樣在訪問數據時刪除和號,我可以使用兩個下標操作符。 我不認爲這是超出界限,因爲第一個循環能夠訪問相同的內存;這是我在第一句話的第一部分回答的問題。但是,我仍然不明白「丟失所有類型信息」的含義。你可以請擴展一下,或者分享一些我可以閱讀更多內容的來源。謝謝。 – user2570380

+0

@ user2570380:當你說'a [1] [2]'時(例如),你需要類型系統以便將a [1]解析到正確的地址(它是數組1的元素0) 。這是因爲地址取決於第二維的*大小*。如果你有一個2x5的'int'數組,第一個下標中的每個增量必須「跳」5個「int」值。您只能使用與運行時類型匹配的靜態類型來執行此操作。如果你只有一個'int *',那麼編譯器或CPU應該怎麼知道它應該用'a [1] [2]'做什麼? – bitmask

1

*arr等於*(arr + 0)等於arr[0]arr[0]只有5 nElements,而不是10這樣調用該函數:

a(*arr, 5, 5); 
2

(&data)[i]顯然是僞造的。 data是一個不是數組的變量。編寫(&data)[0]並將一個變量看作一個元素的數組是合法的。但是,如果i > 0然後您嘗試訪問內存之後存儲data,這不是您擁有的任何內存。 (不要混淆指針data與指向的東西)。

你正在尋找的語法是:

std::cout << data[i * nColumns + j]; 

*當然是乘法,而不是引用操作的。當調用這個函數時,通過將數組視爲一個10元素的1維數組來處理它,所以你需要使用算術來計算出所需的索引。

最後,在函數調用中,*arr應該是(int *)&arr(int *)arr。你實際寫的是arr[0],它是一個5元素的數組。在您的函數中嘗試讀取5個以上的元素是一種超出界限的訪問方式。在實踐中,出於效率原因,編譯器不會嘗試檢測出界限以外的訪問,並且它似乎可以工作。

1

變化在雙行for循環:

std::cout << data[i * nColumns + j];