亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

int[][] 強轉成int**,運行時出錯???

int[][] 強轉成int**,運行時出錯???

C++
慕蓋茨4494581 2018-11-10 11:11:08
void f(int **a) {     cout << a[0][0] << endl;     cout << a[1][0] << endl; } int main()  {      {                   int t1[2];                 int tt[2][2];         tt[0][0] = 1;         tt[0][1] = 2;         tt[1][0] = 3;         tt[1][1] = 4;                 int **ttp = new int*[2];                 for(int i = 0; i < 2; ++i)         {             ttp[i] = new int[2];                         for(int j = 0; j < 2; ++j)             {                 ttp[i][j] = tt[i][j];             }         }                // 此處強轉,在f中訪問[0][0]元素時會出錯。               // 傳入ttp則是好的。         // 錯誤提示:test.exe 中的 0x00ee17bd 處有未經處理的異常: 0xC0000005: 讀取位置 0x00000001 時發生訪問沖突        f((int**)tt);      }         return 0;
查看完整描述

2 回答

?
RISEBY

TA貢獻1856條經驗 獲得超5個贊

樓主是初學C語言嗎?如果是初學者能夠觸探到這樣的問題我認為是大有前途的。

都說C語言最難理解的是指針,而指向指針的指針和二維數組又是最容易搞混的地方,因為二者都通過在前面加兩個*來取值。但二者是完全不同的類型,運算法則完全不一樣。


樓主做強制轉換雖然騙過了編譯器,但接下來執行f里面代碼的時候,a[0][0]是按照*(*(a+0))的方式展開執行的,注意a的類型是指向指針的指針而不是二維數組名,所以括號里面的*(a+0)的執行結果就是1,接下來再執行*1,這個時候把1當作一個地址,試圖把這個地址里面的數據取出來,現在可以明白了,如果不報錯,取到的并非你預期的數據,是一個不可預料的值。之所以報錯是因為運行環境檢測到1這個地址不是本程序有權訪問的(是操作系統的保留內存),所以就報錯了,這里其實就形成了一個野指針。

而假如a的類型是二維數組名,a[0][0]也是按照*(*(a+0))的方式執行的,但此時應注意a是一個行指針,指向二維數據的第一行,a+0=a還是指向二維數據的第一行(a+1就表示指向第二行的行指針),*(a+0)只不過是把行指針轉成了列指針(注意a+0和*(a+0)的值是相同的,只不過類型不同,你可以打印出來看下),接下來再執行最外層的*就是取第一行第一列的值了。

由此可見指向指針的指針和二維數組名取值的運算法則是完全不一樣的,請樓主仔細體會。

 

另外要補充說明的是,二維數組從物理上來說也是一段連續的內存空間,而不應把它想象成

裝著多個一維數組的數組。


查看完整回答
反對 回復 2018-11-14
?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

并不是f[0][0],而是f[0]


查看完整回答
反對 回復 2018-11-14
  • 2 回答
  • 0 關注
  • 824 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號