2010-02-12 4 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** p2DArray = (int**)malloc(rows * cols * sizeof(int)); 

이 정상 인덱싱을 할 수 있습니다 이 같은 것이

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

+1

예. 합계를 할당 한 다음 포인터 계산을 사용하여 prow에 할당 할 부분 이후의 첫 번째 주소에 대한 pcol 포인터를 얻은 다음 pcol 포인터를 걷고 prow 배열을 초기화하는 데 사용합니다. 최종 결과는 하나의 할당이지만 원래 코드와 동일한 레이아웃으로 이루어집니다. –

+0

@Crystal : 코드를 다시 확인하십시오. 루프에 버그가 있습니다. 죄송합니다. –

0

난 당신이 뭘 하려는지에 대해 너무 분명 아니지만, 코드의 마지막 조각은 버그가 : 이것은 지금까지 내가받은 것 같습니다. NULL에 대해 arrayPtr을 테스트하지만 절대로 할당하지 마십시오. for() 루프에서는 arrayPtr에 할당하지만 실제로 아무 것도하지 않습니다.

당신이 무엇이 잘못 후 메모리의 단일 블록을 사용하는 2 차원 배열을 찾는 경우 :

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

? 하나 ALLOC으로 2 차원 배열에 원하는 경우

0

, 당신은 calloc 사용할 수 있습니다 :

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

하거나 malloc을하는 것은 :

int nCellValue = p2DArray[row][col]; 
int* pCell = &p2DArray[row][col]; 
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의 대답은 아마 그 일을 더 나은 방법입니다.