2017-01-03 71 views
-1

我犯了一個函數來創建一個連續的二維陣列是這樣的:Ç毗連二維陣列的通用功能指針運算

void** create2DArray(int row, int col, size_t s) { 
    void *pool = malloc(s * row * col); 
    void **array = malloc(s * row); 

    if(pool==NULL || array==NULL) return NULL; 

    for(int i=0;i<row;i++) { 
     array[i] = pool + i * col * s; 
    } 

    return array; 
} 

功能上面使用這樣的:

int **edge_matrix = create2DArray(num_vertices, num_vertices, sizeof(int)); 

它的工作原理沒有問題。但是有一天,我還以爲我犯了一個錯誤,我改了一行代碼與此:

array[i * s] = pool + i * col * s; 

由於指針運算法則,無效*總是會增加我* 1個字節。我改變了它,所以它會像通常的指針算術一樣增加I * s字節,用於非void *類型。但爲什麼第一個工作,而第二個不工作?

+3

因爲'無效**'是*不*'無效*'。 '* array'具有'void *'類型(即是指針)而不是'void'。你也可能想要實現更強大的錯誤檢查。 –

+0

如果'pool'或'array'分配失敗而另一個成功,則永遠不會分配第一個內存,並最終導致內存泄漏。授予這是一個邊緣案例。 –

+0

代碼中沒有二維數組,也沒有任何指向一個的數組!像'int **'(更糟糕的是,'void **')是一個完全不同的數據結構,不要太喜歡使用類型轉換!這樣的代碼很難維護和理解,它也容易出現類型錯誤 – Olaf

回答

0

您的函數不會創建二維數組,也不會連續存儲內存。你不應該使用指向指針的指針,因爲指針指針和二維數組之間沒有關係。這是一個常見的誤解。

此外,C語言不允許在void指針上進行指針運算。有些編譯器支持將其作爲字符類型的指針運算的非標準擴展。

無論如何,你甚至不需要指針算術。簡單地做:

void* create2DArray (size_t row, size_t col, size_t item_size) 
{ 
    return malloc (item_size * row * col); 
} 

或者,更意味深長:

void create2DArray (size_t row, size_t col, (type** arr_ptr)[row][col]) 
{ 
    *arr_ptr = malloc (sizeof type[row][col]); 
} 


// caller: 
type (*array)[row][col]; 
create2DArray(row, col, &array); 

完整的例子在這裏:Set pointers on Dynamic Matrix