programing

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

goodcopy 2022. 8. 10. 00:14
반응형

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

다음과 같은 것이 있습니다.C코드:

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

잘 작동하죠.단, 다음과 같은 것이 있는 경우:

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

모든 요소에서b길이가 다릅니다.

어떻게 같은 일을 할 수 있을까요?b에 대해 그랬던 것처럼a; 즉, 다음 코드가 맞습니까?

char *c;
size_t size = 2000*sizeof(char *);
c = 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)는, 1개의 할당으로 실행할 수 있습니다.

타입 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=malloc(10*sizeof(char *));

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

이게 이해하기 쉬웠으면 좋겠어요.

2D 어레이 동적 메모리 할당

int **a,i;

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

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

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 malloc(totalLength);

2단계 접근방식이 가장 좋다고 생각합니다.c 2-d 어레이는 어레이의 정의와 어레이이기 때문입니다.첫 번째 단계는 단일 어레이를 할당한 후 각 열에 어레이를 할당하는 것입니다. 글은 세세한 부분까지 잘 알려준다.

malloc은 특정 경계에 할당되지 않으므로 바이트 경계에 할당된다고 가정해야 합니다.

반환된 포인터는 다른 타입으로 변환된 경우 사용할 수 없습니다.이 포인터에 액세스하면 CPU에 의해 메모리액세스 위반이 발생하여 어플리케이션이 즉시 셧다운되기 때문입니다.

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

반응형