다차원 어레이는 메모리에서 어떻게 포맷됩니까?
C에서는 다음 코드를 사용하여 힙에 2차원 배열을 동적으로 할당할 수 있습니다.
int** someNumbers = malloc(arrayRows*sizeof(int*));
for (i = 0; i < arrayRows; i++) {
someNumbers[i] = malloc(arrayColumns*sizeof(int));
}
분명히, 이것은 실제로 여러 개의 분리된 1차원 정수 배열에 대한 포인터의 1차원 배열을 만들어 냅니다. "The System"은 제가 요청했을 때 무엇을 의미하는지 알 수 있습니다.
someNumbers[4][2];
하지만 다음 행과 같이 2D 어레이를 정적으로 선언하면...:
int someNumbers[ARRAY_ROWS][ARRAY_COLUMNS];
...스택에 유사한 구조가 생성됩니까, 아니면 완전히 다른 형태로 생성됩니까?(즉, 포인터의 1D 배열입니까?그렇지 않은 경우, 무엇이며, 이에 대한 참조는 어떻게 파악할 수 있습니까?
또한, 제가 "시스템"이라고 말했을 때, 실제로 무엇이 그것을 알아내는 데 책임이 있나요?알맹이?아니면 C 컴파일러는 컴파일 중에 그것을 분류합니까?
정적인 2차원 어레이는 어레이의 배열처럼 보입니다.메모리에 인접해 배치되어 있을 뿐입니다.어레이는 포인터와 동일하지 않지만, 어레이를 거의 서로 교환하여 사용할 수 있기 때문에 혼란스러울 수 있습니다.그러나 컴파일러는 적절하게 추적하기 때문에 모든 것이 잘 정렬됩니다.에서 말한 배열을 해야 합니다. 왜냐하면 배열을 2D 배열을 하려고 할 왜냐하면 이 어레이를 어떤 함수에 전달하려고 하면int **
파라미터, 나쁜 일이 일어날 수 있습니다.하다
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에 실제로 2D 어레이가 없고 어레이가 있다는 생각에 기초하고 있습니다.이것을 선언하는 경우:
int someNumbers[4][2];
은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★someNumbers
요소로 로, 각 4의 입니다.int [2]
그가 2의 이다).int
퍼즐의 다른 부분은 배열이 항상 메모리에 인접하게 배치된다는 것입니다.필요한 경우:
sometype_t array[4];
그것은 항상 다음과 같이 됩니다.
| sometype_t | sometype_t | sometype_t | sometype_t |
)sometype_t
오브젝트가 서로 옆에 배치되어 있으며, 공백이 없습니다. 당신의 ★★★★★★★★★★★★★★★★★★★★★★★에someNumbers
뭇매를 맞다
| int [2] | int [2] | int [2] | int [2] |
각각의 ★★★★★★★★★★★★★★★★★.int [2]
요소 자체는 다음과 같은 배열입니다.
| int | int |
따라서 전체적으로 다음과 같은 결과가 나타납니다.
| int | int | int | int | int | int | int | int |
를 들어, '우리'가 있다고 .a1
★★★★★★★★★★★★★★★★★」a2
c99):
int a1[2][2] = {{142,143}, {144,145}};
int **a2 = (int* []){ (int []){242,243}, (int []){244,245} };
a1
는 메모리 및에 플레인 입니다.(int*)a1
는 첫 요소에 됩니다.
a1 --> 142 143 144 145
a2
2D의 입니다.int*
(dereference expression, "dereference expression")*a2
으로 int*
메모리 레이아웃이 연속적일 필요는 없습니다.
a2 --> p1 p2
...
p1 --> 242 243
...
p2 --> 244 245
메모리 레이아웃과 액세스 시멘틱스는 전혀 다르지만 어레이 액세스 표현의 C 언어 문법은 동종 2D 어레이와 이종 2D 어레이 모두에서 완전히 동일합니다.
- express
a1[1][0]
.144
a1
에 접속하다 - express
a2[1][0]
.244
a2
에 접속하다
컴파일러는 다음 액세스 식을 알고 있습니다.a1
으로 int[2][2]
"의 경우a2
으로 int**
생성된 어셈블리 코드는 동종 또는 이종 액세스 시멘틱스를 따릅니다.
타입의 이 실행 시 .유형의 배열이int[N][M]
됩니다.int**
예를 들어 다음과 같습니다.
((int**)a1)[1][0] //crash on dereference of a value of type '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'd 배열의 경우 "The System"이 malloc(보통 커널)의 구현자가 됩니다.컴파일러가 할당하는 것은 기본 포인터뿐입니다.
이 컴파일러는 칼이 준 예를 제외하고 항상 그 타입을 그대로 취급합니다.단, 호환성이 있는 용도를 알아낼 수 있습니다.따라서 함수에 [][]를 전달하면 함수는 정적으로 할당된 플랫이라고 가정해야 합니다.여기서 **는 포인터로 간주됩니다.
특정 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' 카테고리의 다른 글
IntelliJ IDEA 기본 JDK 변경 방법 (0) | 2022.07.25 |
---|---|
C 또는 C++로 바이너리 리터럴을 사용할 수 있습니까? (0) | 2022.07.25 |
nuxt의 가져오기 함수 내에서 스토어 액션을 디스패치하려면 어떻게 해야 합니다. (0) | 2022.07.25 |
MinGW를 사용하여 makefile을 컴파일하려면 어떻게 해야 하나요? (0) | 2022.07.25 |
vuex를 사용하여 다른 구성 요소의 Vue 제어 및 업데이트 상태 (0) | 2022.07.25 |