다차원 배열은 메모리에서 어떻게 포맷됩니까?
C에서는 다음 코드를 사용하여 힙에 2 차원 배열을 동적으로 할당 할 수 있다는 것을 알고 있습니다.
int** someNumbers = malloc(arrayRows*sizeof(int*));
for (i = 0; i < arrayRows; i++) {
someNumbers[i] = malloc(arrayColumns*sizeof(int));
}
분명히 이것은 실제로 정수로 구성된 여러 개의 1 차원 배열에 대한 포인터의 1 차원 배열을 만들고 "시스템"은 내가 요청할 때 의미하는 바를 알아낼 수 있습니다.
someNumbers[4][2];
그러나 다음 줄과 같이 2D 배열을 정적으로 선언하면 ... :
int someNumbers[ARRAY_ROWS][ARRAY_COLUMNS];
... 스택에서 유사한 구조가 생성됩니까? 아니면 완전히 다른 형태입니까? (즉, 포인터의 1D 배열입니까? 그렇지 않은 경우, 무엇이며, 이에 대한 참조는 어떻게 파악됩니까?)
또한 "시스템"이라고 말했을 때 실제로 그것을 알아내는 데 책임이있는 것은 무엇입니까? 커널? 아니면 C 컴파일러가 컴파일하는 동안 정렬합니까?
정적 2 차원 배열은 배열 배열처럼 보입니다. 메모리에 연속적으로 배치되어 있습니다. 배열은 포인터와 같지 않지만, 종종 그것들을 거의 상호 교환 적으로 사용할 수 있기 때문에 때때로 혼란 스러울 수 있습니다. 그러나 컴파일러는 올바르게 추적하므로 모든 것이 잘 정렬됩니다. 언급 한 것처럼 정적 2D 배열에주의해야합니다. int **
매개 변수 를받는 함수에 1을 전달하려고하면 나쁜 일이 발생할 수 있기 때문입니다. 다음은 간단한 예입니다.
int array1[3][2] = {{0, 1}, {2, 3}, {4, 5}};
메모리에서 다음과 같습니다.
0 1 2 3 4 5
정확히 다음과 같습니다.
int array2[6] = { 0, 1, 2, 3, 4, 5 };
그러나이 array1
기능 에 전달하려고하면 :
void function1(int **a);
경고 메시지가 표시되고 앱이 배열에 올바르게 액세스하지 못합니다.
warning: passing argument 1 of ‘function1’ from incompatible pointer type
2D 배열이와 같지 않기 때문 int **
입니다. 배열에서 포인터로의 자동 소멸은 말하기를 "한 수준 깊이"만 진행합니다. 함수를 다음과 같이 선언해야합니다.
void function2(int a[][2]);
또는
void function2(int a[3][2]);
모든 것을 행복하게 만듭니다.
이 같은 개념은 n 차원 배열로 확장됩니다 . 응용 프로그램에서 이러한 종류의 재미있는 비즈니스를 활용하면 일반적으로 이해하기가 더 어려워집니다. 그러니 조심하세요
답은 C가 정말하지 않는 생각을 기반으로 이 2 차원 배열을 - 그것은 배열 - 중 - 배열을 가지고있다. 이것을 선언하면 :
int someNumbers[4][2];
someNumbers
4 개의 요소로 구성된 배열을 요구합니다 . 여기서 해당 배열의 각 요소는 유형입니다 int [2]
(자체 배열은 2 int
초).
퍼즐의 다른 부분은 배열이 항상 메모리에 연속적으로 배치된다는 것입니다. 요청하는 경우 :
sometype_t array[4];
그러면 항상 다음과 같이 보일 것입니다.
| sometype_t | sometype_t | sometype_t | sometype_t |
(4 개의 sometype_t
물체가 서로 간격을두고 배치되지 않음). 따라서 someNumbers
배열 배열에서 다음과 같이 나타납니다.
| int [2] | int [2] | int [2] | int [2] |
그리고 각 int [2]
요소 자체는 다음과 같은 배열입니다.
| int | int |
전체적으로 다음과 같은 결과를 얻습니다.
| int | int | int | int | int | int | int | int |
unsigned char MultiArray[5][2]={{0,1},{2,3},{4,5},{6,7},{8,9}};
메모리에서 다음과 같습니다.
unsigned char SingleArray[10]={0,1,2,3,4,5,6,7,8,9};
컴파일러도 많은 노력을 기울이고 있지만 둘 다 대답합니다.
정적으로 할당 된 배열의 경우 "시스템"이 컴파일러가됩니다. 스택 변수처럼 메모리를 예약합니다.
malloc의 배열의 경우, "시스템"은 malloc (일반적으로 커널)의 구현자가됩니다. 컴파일러가 할당 할 모든 것은 기본 포인터입니다.
컴파일러는 Carl이 상호 교환 가능한 사용법을 파악할 수있는 위치에서 제공 한 예를 제외하고는 선언 된대로 항상 형식을 처리합니다. 따라서 [] []를 함수에 전달하면 정적으로 할당 된 플랫이라고 가정해야합니다. 여기서 **는 포인터를 가리키는 포인터입니다.
특정 2D 배열에 액세스하려면 아래 코드와 같이 배열 선언에 대한 메모리 맵을 고려하십시오.
0 1
a[0]0 1
a[1]2 3
각 요소에 액세스하려면 매개 변수로 관심있는 배열을 함수에 전달하기에 충분합니다. 그런 다음 열에 오프셋을 사용하여 각 요소에 개별적으로 액세스하십시오.
int a[2][2] ={{0,1},{2,3}};
void f1(int *ptr);
void f1(int *ptr)
{
int a=0;
int b=0;
a=ptr[0];
b=ptr[1];
printf("%d\n",a);
printf("%d\n",b);
}
int main()
{
f1(a[0]);
f1(a[1]);
return 0;
}
참고 URL : https://stackoverflow.com/questions/2565039/how-are-multi-dimensional-arrays-formatted-in-memory
'programing tip' 카테고리의 다른 글
힙 손상 오류를 디버깅하는 방법? (0) | 2020.06.01 |
---|---|
jquery“$ .post”요청을 동 기적으로 만드는 방법 (0) | 2020.06.01 |
HTML에서 CDATA 란 무엇입니까? (0) | 2020.06.01 |
검색 주소창이 iOS / Android / Mobile Chrome을 숨기면 배경 이미지가 점프 함 (0) | 2020.06.01 |
빌드 풍미 사용-소스 폴더 구조 및 올바르게 build.gradle (0) | 2020.06.01 |