2010-02-12 95 views
1

我想在一個函數調用中創建一個連續的內存塊,該函數調用將第一部分內存作爲指針數組指向其他塊。基本上,我試圖做到:與malloc連續內存塊

int **CreateInt2D(size_t rows, size_t cols) 
{ 
    int **p, **p1, **end; 
    p = (int **)SafeMalloc(rows * sizeof(int *)); 
    cols *= sizeof(int); 
    for (end = p + rows, p1 = p; p1 < end; ++p1) 
     *p1 = (int *)SafeMalloc(cols); 
    return(p); 
} 

void *SafeMalloc(size_t size) 
{ 
    void *vp; 

    if ((vp = malloc(size)) == NULL) { 
     fputs("Out of mem", stderr); 
     exit(EXIT_FAILURE); 
    } 
    return(vp); 
} 

但有一個塊。這是據我已經得到了:

int *Create2D(size_t rows, size_t cols) { 
int **memBlock; 
int **arrayPtr; 
int loopCount; 
    memBlock = (int **)malloc(rows * sizeof(int *) + rows * cols * sizeof(int)); 
    if (arrayPtr == NULL) { 
     printf("Failed to allocate space, exiting..."); 
     exit(EXIT_FAILURE); 
    } 
    for (loopCount = 1; loopCount <= (int)rows; loopCount++) { 
     arrayPtr = memBlock + (loopCount * sizeof(int *)); 
     //I don't think this part is right. do I need something like arrayPtr[loopCount] = .... 
    } 
return(memBlock); 
} 

回答

1

像這樣的東西

int **Create2D(size_t rows, size_t cols) 
{ 
    size_t cb = (rows * sizeof(int *)) + (rows * cols * sizeof(int)); 
    int * pmem = (int *)SafeMalloc(cb); 

    int ** prows = (int **)pmem; 
    int * pcol = (int *)&prows[rows]; // point pcol after the last row pointer 

    for (int ii = 0; ii < rows; ++ii) 
    { 
     prows[ii] = pcol; 
     pcol += cols; 
    } 

    return prows; 
} 
+0

我想我得到你的答案,但我在爲行指針和列分配內存的想法有問題。因此,對於那塊內存,cb,你可以只是將pmem部分分類來分割它?像第一部分是指向指針的指針,然後指向最後一行指針的pcol,然後初始化cols並讓指針指向的指針指向pcol?像那樣的東西? – Crystal 2010-02-12 09:50:32

+1

是的。你分配總數,然後使用指針數學得到一個pcol指針,指向第一個地址_after_你想要分配給prows的部分,然後遍歷pcol指針並使用它來初始化prow數組。最終的結果是一個分配,但與原始代碼具有相同的佈局。 – 2010-02-12 09:55:21

+0

@Crystal:再次檢查代碼,我有一個循環中的錯誤。抱歉。 – 2010-02-12 10:01:07

0

我不太清楚你想要做什麼,而是你的代碼的最後一塊是馬車。您針對NULL測試arrayPtr,但從不分配它。在您分配給arrayPtr的for()循環中,但實際上並沒有對它做任何事情。

如果您正在尋找使用一個單獨的內存塊,然後有什麼錯一個二維數組:

int* array = (int*)malloc(rows * count * sizeof(int)); 
int* someCellPtr = &array[y * rows + x]; 

0

,如果你想二維數組與一個頁頭,您可以使用calloc

int** p2DArray = (int**)calloc(rows,cols * sizeof(int)); 

或只是malloc的:

int** p2DArray = (int**)malloc(rows * cols * sizeof(int)); 

這使正常的索引:

​​
1

看來你並沒有清楚的描述你想要什麼 來實現。 記錄它!它會清除你的思想,除此之外,如果你不明白它,沒有人會和 這樣的代碼是一個噩夢來維持(即使時間 通過時,甚至適用於你自己)。

要創建一個分配連續內存塊的函數,必須調用SafeMalloc一次,並使用一次將使用的內存總量。

/* 
* Memory layout example for 2 rows and 3 cols 
* 
*      1 1 1 1 1 1 1 1 1 1 
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
* |P|P|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C| 
* |1|2|1|1|1|2|2|2|3|3|3|1|1|1|2|2|2|3|3|3| 
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
* 
* P1 is a pointer coloum data for row 1, points to memory start + offset 2 (assuming sizeof(int) == sizeof(int *)) 
* P2 is for row 2, points to memory start + offset 11 
* C1 is coloumn 1 data, etc 
*/ 
int **CreateInt2D(size_t rows, size_t cols) 
{ 
     int **memory_start, **p1, *col_data; 
     size_t total_memory_to_allocate; 

     total_memory_to_allocate = rows * sizeof(int *) + rows * cols * sizeof(int); 
     memory_start = (int **) SafeMalloc(total_memory_to_allocate); 

     for (col_data = (int *)(memory_start + rows), p1 = memory_start; 
      p1 < (int **)col_data; 
      ++p1, col_data += cols * sizeof(int)) 
       *p1 = col_data; 

     return memory_start; 
} 

這個例子是基於儘可能地貼近你的原始越好,約翰Knoeller的答案通過陣列認購大概是這樣做的更好的方法。