2012-12-19 213 views
1

我遇到了指向二維數組的指針問題。指針應指向一個可變大小的數組。C指針指向2維數組

// create pointer to 2 dimensional array 
TimeSlot **systemMatrix; // this is a global variable 

在函數中我想創建一個新的數組。

void setup(uint16_t lines, uint16_t coloumns) { 
    // create 2 dimensional array. size can be set here. 
    TimeSlot tmpTimeSlots[lines][coloumns]; 

    // make the pointer point to this array 
    systemMatrix = tmpTimeSlots; // WARNING 
} 

但是,當我讓指針指向數組編譯器說:「警告:從不兼容指針類型賦值」。另外,當從另一個函數訪問systemmatrix [2] [5]時,運行軟件的mikrocontroller會出現硬故障。

稍後訪問tmpTimeSlots的元素時需要變量systemMatrix。

我試着像組合

systemMatrix = *(*tmpTimeSlot); 

等,但他們都不工作。

任何幫助表示讚賞:) 謝謝!

編輯:好的問題理解和解決,非常感謝!

+1

二維數組不會轉換爲雙指針。 –

回答

6

二維數組!!=雙指針。

你幾乎肯定需要動態內存分配。你也想深拷貝數組的內容 - 它是一個非靜態的局部變量,所以它的作用域是無效的。因此你不能做TYPE arr[sz]; return arr;

const size_t width = 3; 
const size_t height = 5; 
TimeSlot tmpTimeSlot[width][height]; 

systemMatrix = malloc(width * sizeof systemMatrix[0]); 
for (int i = 0; i < width; i++) { 
    systemMatrix[i] = malloc(height * sizeof systemMatrix[i][0]); 
    for (int j = 0; j < height; j++) { 
     systemMatrix[i][j] = tmpTimeSlot[i][j]; 
    } 
} 
1

您正試圖保存一個指向本地對象(分配在堆棧上)的指針並在超出作用域後使用它。這是錯誤的,指針將在函數完成後失效。

另外。閱讀關於這個問題的答案:Heap allocate a 2D array (not array of pointers)瞭解如何動態地分配一個二維數組(在堆上,與堆棧相反)。

+1

不僅如此,而且雙指針是指向多維數組的錯誤類型。 –

+0

@MatteoItalia是的,但這是馬丁需要理解的第一件事:) – piokuc

4

您的systemMatrix指針不是指向二維數組的指針,而是雙引用。您需要像這樣聲明:TimeSlot (*systemMatrix)[columns]; - 這是2D數組指針的正確類型。但是,您需要在聲明地點(C99)或常量​​(C99之前)處知道值columns

此外,返回一個指向局部變量的指針將導致函數返回後的懸掛指針。

1

兩個問題:

  1. 你不能返回一個指針爲自動存儲。該功能一旦離開,該存儲就會超出範圍。你應該使用malloc()來代替。使用超出範圍的存儲可能會訪問堆棧中的垃圾,這可能會導致硬故障。從技術上講,這稱爲未定義的行爲在C.
  2. 與您的聲明相反,TimeSlot **systemMatrix;不聲明二維數組,但是指向指向Timeslot的指針。有關如何動態創建多維數組,請參見comp.lang.c FAQ
2

這裏有幾個錯誤。

TimeSlot **systemMatrix; 

這不能用於指向C多維數組(稍後聲明);相反,它可以用來指向矢量矢量,這是一個不同的野獸(看看你的C書的更多細節)。問題的關鍵是,指向一個多維數組你應該有這樣的聲明:

TimeSlot (* systemMatrix)[lines]; 

這是一個指向長度lines的載體,可用於處理多維陣列(見here更多細節)。現在,這需要在編譯時知道lines,所以它不適合您的情況。

即使您的systemMatrix聲明對於您在該函數中執行的任務是正確的,您將爲該指針指定分配給該函數的內存地址,該函數在函數退出後不再存在 - 因此您的systemMatrix會只要setup返回,就成爲無效指針。

您需要的是內存的動態分配。這使您可以指定該內存的任意生命週期並使用雙括號語法。首先,你分配一個與你需要的行數一樣大的指針向量(在malloc的調用中乘以sizeof(int *));然後,然後,您分配行向量並將它們中的每一個分配到它在列向量中的位置。有關此(和其他)動態分配多維向量的解決方案的更多詳細信息,請參見this answer

不要忘了free每個分配的向量,當你不再需要它們了!