code

행 길이가 다른 다차원 배열 할당에 malloc 사용

codestyles 2020. 11. 13. 08:13
반응형

행 길이가 다른 다차원 배열 할당에 malloc 사용


다음 C코드가 있습니다.

int *a;
size_t size = 2000*sizeof(int);
a = (int *) malloc(size);

잘 작동합니다. 하지만 다음과 같은 경우 :

char **b = malloc(2000*sizeof *b);

의 모든 요소는 b길이가 다릅니다.

b내가했던 것과 같은 일을 어떻게 할 수 있습니까 a? 즉, 다음 코드가 정확할까요?

char *c;
size_t size = 2000*sizeof(char *);
c = (char *) malloc(size);

먼저와 같은 포인터 배열을 할당 char **c = malloc( N * sizeof( char* ))한 다음 malloc루프에서 별도의 호출로 각 행을 할당 해야합니다.


/* N is the number of rows  */
/* note: c is char** */
if (( c = malloc( N*sizeof( char* ))) == NULL )
{ /* error */ }

for ( i = 0; i < N; i++ )
{
  /* x_i here is the size of given row, no need to
   * multiply by sizeof( char ), it's always 1
   */
  if (( c[i] = malloc( x_i )) == NULL )
  { /* error */ }

  /* probably init the row here */
}

/* access matrix elements: c[i] give you a pointer
 * to the row array, c[i][j] indexes an element
 */
c[i][j] = 'a';

총 요소 수 (예 :)를 알고있는 경우 N*M단일 할당에서이를 수행 할 수 있습니다.


T 유형의 NxM 배열을 동적으로 할당하는 일반적인 형식은 다음과 같습니다.

T **a = malloc(sizeof *a * N);
if (a)
{
  for (i = 0; i < N; i++)
  {
    a[i] = malloc(sizeof *a[i] * M);
  }
}

배열의 각 요소의 길이가 다른 경우 M을 해당 요소의 적절한 길이로 대체하십시오. 예를 들면

T **a = malloc(sizeof *a * N);
if (a)
{
  for (i = 0; i < N; i++)
  {
    a[i] = malloc(sizeof *a[i] * length_for_this_element);
  }
}

에 대한 동등한 메모리 할당은 char a[10][20]다음과 같습니다.

char **a;

a=(char **) malloc(10*sizeof(char *));

for(i=0;i<10;i++)
    a[i]=(char *) malloc(20*sizeof(char));

이해하기 간단 해 보이길 바랍니다.


다른 방법은 행에 대한 포인터를위한 헤더 블록과 실제 데이터를 행에 저장하기위한 본문 블록으로 구성된 하나의 연속적인 메모리 청크를 할당하는 것입니다. 그런 다음 본문의 메모리 주소를 행 단위로 헤더의 포인터에 할당하여 메모리를 마크 업하십시오. 다음과 같습니다.

int** 2dAlloc(int rows, int* columns) {    
    int header = rows * sizeof(int*);

    int body = 0;
    for(int i=0; i<rows; body+=columnSizes[i++]) {  
    }
    body*=sizeof(int);

    int** rowptr = (int**)malloc(header + body);

    int* buf  = (int*)(rowptr + rows);
    rowptr[0] = buf;
    int k;
    for(k = 1; k < rows; ++k) {
        rowptr[k] = rowptr[k-1] + columns[k-1];
    }
    return rowptr;
}

int main() {
    // specifying column amount on per-row basis
    int columns[] = {1,2,3};
    int rows = sizeof(columns)/sizeof(int);
    int** matrix = 2dAlloc(rows, &columns);

    // using allocated array
    for(int i = 0; i<rows; ++i) {
        for(int j = 0; j<columns[i]; ++j) {
            cout<<matrix[i][j]<<", ";
        }   
            cout<<endl;
    }

    // now it is time to get rid of allocated 
    // memory in only one call to "free"
    free matrix;
}

이 접근 방식의 장점은 메모리를 효율적으로 해제하고 배열과 유사한 표기법을 사용하여 결과 2D 배열의 요소에 액세스 할 수 있다는 것입니다.


b의 모든 요소의 길이가 다른 경우 다음과 같이해야합니다.

int totalLength = 0;
for_every_element_in_b {
    totalLength += length_of_this_b_in_bytes;
}
return (char **)malloc(totalLength);

I think a 2 step approach is best, because c 2-d arrays are just and array of arrays. The first step is to allocate a single array, then loop through it allocating arrays for each column as you go. This article gives good detail.


2-D Array Dynamic Memory Allocation

int **a,i;

// for any number of rows & columns this will work
a = (int **)malloc(rows*sizeof(int *));
for(i=0;i<rows;i++)
    *(a+i) = (int *)malloc(cols*sizeof(int));

malloc does not allocate on specific boundaries, so it must be assumed that it allocates on a byte boundary.

The returned pointer can then not be used if converted to any other type, since accessing that pointer will probably produce a memory access violation by the CPU, and the application will be immediately shut down.

참고URL : https://stackoverflow.com/questions/1970698/using-malloc-for-allocation-of-multi-dimensional-arrays-with-different-row-lengt

반응형