2013-11-21 72 views
2

我感興趣的是不同的方式來分配內存在堆中的二維數組。內存分配指針指向數組和指針指針

當訪問指向指向一個或多個維度數組的指針和指針的指針時,似乎使用相同的符號。我希望能有人澄清每個人的差異和用處。他們都對嗎?

這個第一方式將陣列作爲指針存儲到指針:

char **createTable(int r, int c) { 
    char **table; 
    int i; 
    char *offset; 
    table = malloc(r * sizeof (char *) + r * c * sizeof (char)); 
    if (!table) return NULL; 
    offset = (char *) table + sizeof (char *) * r; 
    for (i = 0; i < r; i++) { 
     table[i] = offset + c * i; 
    } 
    return table; 
} 

該其他方式似乎更快。我想不出一種很好的方式來包裝它像另一個功能。

char (*table)[c]; 
table = (char (*)[c]) calloc(r * c, sizeof (char)); 

我的理解是,即使數組就像靜態指針,數組有能力有自己的幾個維度?

這是真的,我描述的第一種方式是正統的方式?

+1

兩者似乎都做同樣的事情。第二個絕對更優雅。 –

+0

爲什麼不只是'char table [r] [c]'?我猜你的意圖是,將有可能從分配它的函數返回指針?在問題中明確說明這一點可能很有用,所以我們知道你爲什麼不只是在執行'char table [r] [c];' –

+0

更具體地說:你不能返回'table',其中'table '是'char(* table)[c];'來自返回'char **'的函數。鏗鏘:'不兼容的指針類型返回'char(*)[c]'從結果類型'char **'的函數' –

回答

1

不幸的是,似乎沒有辦法讓一個函數返回一個指向可變長度數組的指針,該指針將被正確輸入。你可以去像這樣的伎倆:

#include <stddef.h> 
#include <stdlib.h> 

void* createTable_(size_t r, size_t c) { 
    char (*table)[c] = malloc(sizeof(char[r][c])); 
    /* do the intialization that you need */ 
    return table; 
} 

#define createTable(R, C) ((char(*)[C])createTable_((R), (C))) 

int main(int argc, char*argv[]) { 
    char (*table)[argc] = createTable(argc, argc); 
} 

的功能只是返回一個指針void*和宏確保正確的打字。不幸的是,這樣一個宏必須對第二個參數進行兩次評估,所以要小心副作用。

編輯,爲你問問其他子問題:

我不會把指針模擬多維矩陣「正統」的指針方式,只是過時。至少對於我所見過的最常用的東西來說是如此。

  • 這很容易出錯。你真的必須得到所有索引計算 正確的。 BTW有你也可以得到更多的東西可讀,通過使用 sizeof陣列上,像

    malloc(sizeof (char*[r]) + sizeof (char[r][c]))

  • 它浪費的空間,sizeof(char*[c])部分

  • 它是低效率的,而不是簡單的指數計算,它必須做一個額外的間接。

  • 它與使用大量矩陣的其他語言(如Fortran)不兼容。

+0

這是你回答的部分的一個很好的答案,但比較兩種方法的部分將不勝感激。 – niic