programing

다차원 어레이는 메모리에서 어떻게 포맷됩니까?

prostudy 2022. 7. 25. 22:19
반응형

다차원 어레이는 메모리에서 어떻게 포맷됩니까?

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 ★★★★★★★★★★★★★★★★★」a2c99):

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 어레이 모두에서 완전히 동일합니다.

  • expressa1[1][0].144 a1에 접속하다
  • expressa2[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

반응형