행 길이가 다른 다차원 배열 할당에 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
'programing' 카테고리의 다른 글
exit() 함수 사용 (0) | 2022.08.10 |
---|---|
Vue Draggable - 드롭할 요소에 액세스합니다. (0) | 2022.08.10 |
"backspace" 이스케이프 문자 "\b": 예기치 않은 동작? (0) | 2022.08.10 |
왜 C자 리터럴은 chars가 아닌 int일까요? (0) | 2022.08.10 |
목록에서 선택한 요소를 변경하면 Vue.js가 전환됩니다. (0) | 2022.08.10 |