One malloc 문을 사용하여 2-D 배열을 할당하는 방법
저는 인터뷰에서 2-D 배열을 어떻게 할당하는지 질문을 받았고, 아래가 제 해결책이었습니다.
#include <stdlib.h>
int **array;
array = malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
{
array[i] = malloc(ncolumns * sizeof(int));
if(array[i] == NULL)
{
fprintf(stderr, "out of memory\n");
exit or return
}
}
나는 내가 잘했다고 생각했는데 그는 나에게 그것을 사용해서 하라고 했습니다.malloc()
두개가 아닌 진술.저는 그것을 어떻게 달성해야 할지 전혀 모르겠습니다.
혼자 할 수 있는 방법을 제안해 줄 수 있는 사람?malloc()
?
두 가지 모두에 필요한 총 메모리 양을 계산하기만 하면 됩니다.nrows
행 pointers와 실제 데이터를 모두 합산한 후 한 번의 통화를 수행합니다.
int **array = malloc(nrows * sizeof *array + (nrows * (ncolumns * sizeof **array));
너무 복잡해 보이는 경우에는 크기 표현식의 다른 용어를 지정하여 이를 분할하여 약간의 자체 문서화할 수 있습니다.
int **array; /* Declare this first so we can use it with sizeof. */
const size_t row_pointers_bytes = nrows * sizeof *array;
const size_t row_elements_bytes = ncolumns * sizeof **array;
array = malloc(row_pointers_bytes + nrows * row_elements_bytes);
그런 다음 각 행의 포인터가 해당 행의 첫 번째 요소를 가리킬 수 있도록 행 포인터를 검토하고 초기화해야 합니다.
size_t i;
int * const data = array + nrows;
for(i = 0; i < nrows; i++)
array[i] = data + i * ncolumns;
결과적인 구조는 예를 들어 당신이 얻는 것과 미묘하게 다르다는 것에 유의하십시오.int array[nrows][ncolumns]
, 명시적인 행 포인터가 있기 때문에 이렇게 할당된 배열의 경우 모든 행에 동일한 수의 열이 있어야 한다는 실질적인 요구 사항은 없습니다.
그것은 또한 다음과 같은 접근을 의미합니다.array[2][3]
실제 2D 배열로 유사한 모양의 액세스와 구별되는 작업을 수행합니다.이 경우 가장 안쪽에 있는 접근이 먼저 일어나고,array[2]
세번째 요소에서 포인터를 읽어냅니다.array
. 그런 다음 포인터를 (열) 배열의 기본으로 취급하고, 이 배열 안으로 색인을 붙여 네 번째 요소를 가져옵니다.
그에 비해, 어떤 것에 대해서는
int array2[4][3];
12개의 정수의 공간을 차지하는 "포장된" 적절한 2D 배열입니다. 접근은 다음과 같습니다.array[3][2]
는 단순히 요소를 얻기 위해 기본 주소에 오프셋을 추가하는 것으로 분류됩니다.
int **array = malloc (nrows * sizeof(int *) + (nrows * (ncolumns * sizeof(int)));
이것은 C에서 배열들이 바이트들의 묶음으로서 차례로 모든 요소들이기 때문에 작동합니다.메타데이터 같은 것이 없습니다. malloc()는 배열에서 문자, int 또는 줄로 사용하기 위해 할당하는 것인지 알 수 없습니다.
그런 다음 초기화해야 합니다.
int *offs = &array[nrows]; /* same as int *offs = array + nrows; */
for (i = 0; i < nrows; i++, offs += ncolumns) {
array[i] = offs;
}
다른 방법이 있습니다.
컴파일 시 열 수를 알고 있다면 다음과 같은 작업을 수행할 수 있습니다.
#define COLS ... // integer value > 0
...
size_t rows;
int (*arr)[COLS];
... // get number of rows
arr = malloc(sizeof *arr * rows);
if (arr)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < COLS; j++)
arr[i][j] = ...;
}
C99에서 작업하는 경우 VLA의 포인터를 사용할 수 있습니다.
size_t rows, cols;
... // get rows and cols
int (*arr)[cols] = malloc(sizeof *arr * rows);
if (arr)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
arr[i][j] = ...;
}
One malloc 문(?)을 사용하여 2-D 배열을 할당하는 방법
아직까지 진정한 2D 배열을 위해 메모리를 할당하는 답변은 없습니다.
int **array
int에 대한 포인터입니다.array
는 2D 배열의 포인터가 아닙니다.
int a[2][3]
int의 배열 3의 실제 2D 배열 또는 배열 2의 예입니다.
C99를 사용하여 실제 2D 배열을 위한 메모리를 할당하려면 다음을 사용합니다.malloc()
VLA(Variable-Length Array)의 포인터에 저장합니다.
// Simply allocate and initialize in one line of code
int (*c)[nrows][ncolumns] = malloc(sizeof *c);
if (c == NULL) {
fprintf(stderr, "out of memory\n");
return;
}
// Use c
(*c)[1][2] = rand();
...
free(c);
VLA 지원 없이 치수가 상수인 경우 코드가
#define NROW 4
#define NCOL 5
int (*d)[NROW][NCOL] = malloc(sizeof *d);
이 작업을 수행할 수 있어야 합니다. (모든 캐스팅에서 약간 추합니다.)
int** array;
size_t pitch, ptrs, i;
char* base;
pitch = rows * sizeof(int);
ptrs = sizeof(int*) * rows;
array = (int**)malloc((columns * pitch) + ptrs);
base = (char*)array + ptrs;
for(i = 0; i < rows; i++)
{
array[i] = (int*)(base + (pitch * i));
}
저는 다차원 배열 패러다임을 해결하기 위한 이러한 "배열 포인터 배열"의 팬이 아닙니다.배열[행 * cols + col]로 요소에 액세스할 때 항상 단일 차원 배열을 선호합니까?클래스의 모든 것을 캡슐화하고 'at' 메서드를 구현하는 데 문제가 없습니다.
Matrix[i][j]라는 표기를 사용하여 배열의 멤버에 액세스하려면 약간의 C++ 마법을 수행할 수 있습니다.@John 솔루션은 이러한 방식으로 수행하려고 하지만 컴파일 시간에 열의 수를 알아야 합니다.일부 C++와 연산자[]를 재정의하면 다음을 완전히 얻을 수 있습니다.
class Row
{
private:
int* _p;
public:
Row( int* p ) { _p = p; }
int& operator[](int col) { return _p[col]; }
};
class Matrix
{
private:
int* _p;
int _cols;
public:
Matrix( int rows, int cols ) { _cols=cols; _p = (int*)malloc(rows*cols ); }
Row operator[](int row) { return _p + row*_cols; }
};
이제 행렬 개체를 사용하여 곱셈 테이블을 만들 수 있습니다.
Matrix mtrx(rows, cols);
for( i=0; i<rows; ++i ) {
for( j=0; j<rows; ++j ) {
mtrx[i][j] = i*j;
}
}
이제 옵티마이저가 옳은 일을 하고 있고 통화 기능이나 다른 종류의 오버헤드가 없기 때문입니다.생성자를 호출하지 않습니다.함수 간에 행렬을 이동하지 않는 한 _cols 변수도 생성되지 않습니다.문 mtrx[i][j]는 기본적으로 mtrx[i*cols+j]를 수행합니다.
다음과 같이 수행할 수 있습니다.
#define NUM_ROWS 10
#define NUM_COLS 10
int main(int argc, char **argv)
{
char (*p)[NUM_COLS] = NULL;
p = malloc(NUM_ROWS * NUM_COLS);
memset(p, 81, NUM_ROWS * NUM_COLS);
p[2][3] = 'a';
for (int i = 0; i < NUM_ROWS; i++) {
for (int j = 0; j < NUM_COLS; j++) {
printf("%c\t", p[i][j]);
}
printf("\n");
}
} // end of main
합니다.(row*column) * sizeof(int)
malloc리를 .여기 시연할 코드 조각이 있습니다.
int row = 3, col = 4;
int *arr = (int *)malloc(row * col * sizeof(int));
int i, j, count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i*col + j) = ++count; //row major memory layout
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", *(arr + i*col + j));
언급URL : https://stackoverflow.com/questions/8740195/how-do-we-allocate-a-2-d-array-using-one-malloc-statement
'programing' 카테고리의 다른 글
jQuery UI 대화 상자 - 닫은 후에 열리지 않음 (0) | 2023.09.19 |
---|---|
순수 자바스크립트는 입력 값 변경을 듣기 (0) | 2023.09.19 |
임시 NSManaged Object 인스턴스를 처리하는 방법은 무엇입니까? (0) | 2023.09.19 |
f-스트링이 있는 라운딩 플로트 (0) | 2023.09.19 |
브라우저의 보이는 부분에 들어가면 이미지가 로드됩니까? (0) | 2023.09.19 |