programing

C: 다차원 어레이의 메모리를 올바르게 확보

newsource 2023. 6. 9. 22:05

C: 다차원 어레이의 메모리를 올바르게 확보

다차원 배열을 초기화하는 다음 ANSIC 코드가 있다고 가정합니다.

int main()
{
      int i, m = 5, n = 20;
      int **a = malloc(m * sizeof(int *));

      //Initialize the arrays
      for (i = 0; i < m; i++) { 
          a[i]=malloc(n * sizeof(int));
      }

      //...do something with arrays

      //How do I free the **a ?

      return 0;
}

사용 후**a어떻게 하면 정확하게 메모리에서 자유로울 수 있습니까?


[업데이트] (솔루션)

Tim(및 기타)의 답변 덕분에 이제 다차원 배열에서 메모리를 확보하는 기능을 수행할 수 있습니다.

void freeArray(int **a, int m) {
    int i;
    for (i = 0; i < m; ++i) {
        free(a[i]);
    }
    free(a);
}

좋아요, 정확히 어떤 순서가 필요한지 설명하는 것은 꽤 혼란스럽습니다.free()전화가 걸려와야 하니까, 사람들이 무엇을 얻으려고 하는지, 왜 그러는지 설명해 보겠습니다.

기본 사항부터 시작하여, 다음을 사용하여 할당된 메모리를 비웁니다.malloc()당신은 간단히 전화합니다.free()정확히 당신이 준 포인터로.malloc()이 코드의 경우:

int **a = malloc(m * sizeof(int *));

일치하는 항목이 필요합니다.

free(a);

이 줄의 경우:

a[i]=malloc(n * sizeof(int));

일치하는 항목이 필요합니다.

free(a[i]);

비슷한 루프 안에.

이것이 복잡해지는 것은 이것이 발생해야 하는 순서입니다.전화하시면malloc()여러 개의 서로 다른 메모리 덩어리를 얻기 위해 여러 번, 일반적으로 어떤 순서를 부르든 상관 없습니다.free()당신이 그들을 다 처리했을 때.그러나, 여기서 순서는 매우 구체적인 이유로 중요합니다: 당신은 하나의 덩어리를 사용하고 있습니다.malloc다른 청크에 대한 포인터를 보유하기 위한 편집 메모리malloc 기억에 남는 것메모리를 반환한 후에는 메모리를 읽거나 쓰려고 하면 안 되기 때문입니다.free()이것은 당신이 그것들의 포인터들이 저장된 청크들을 자유롭게 해야 한다는 것을 의미합니다.a[i] 당신이 자유롭게 하기 전에a청크 자체입니다.포인터가 저장된 개별 청크a[i]서로 의존하지 않으며, 그럴 수 있습니다.free당신이 원하는 순서대로 d.

이 모든 것을 종합하면 다음과 같습니다.

for (i = 0; i < m; i++) { 
  free(a[i]);
}
free(a);

마지막 팁: 전화할 때malloc()변경을 고려해 보십시오.

int **a = malloc(m * sizeof(int *));

a[i]=malloc(n * sizeof(int));

대상:

int **a = malloc(m * sizeof(*a));

a[i]=malloc(n * sizeof(*(a[i])));

이게 무슨 짓입니까?컴파일러는 다음을 알고 있습니다.a이다.int **그래서 그것은 그것을 결정할 수 있습니다.sizeof(*a)와 동일합니다.sizeof(int *)하지만, 나중에 당신이 생각을 바꾸고 원한다면,char상심한short상심한longs 또는 당신의 배열에 있는 것 대신에.ints, 또는 나중에 다른 곳에서 사용할 수 있도록 이 코드를 수정하면 남은 참조 하나만 변경해야 합니다.int위의 첫 번째 따옴표로 묶은 줄에서, 그리고 다른 모든 것들은 자동으로 당신을 위해 제자리에 놓일 것입니다.이렇게 하면 향후에 인식되지 않는 오류가 발생할 가능성이 제거됩니다.

행운을 빕니다.

할당한 것을 정확하게 실행 취소:

  for (i = 0; i < m; i++) { 
      free(a[i]);
  }
  free(a);

메모리를 원래 할당한 순서와 반대로 이 작업을 수행해야 합니다.그랬다면,free(a) 그 다음에 그다, 음에저.a[i]메모리가 해제된 후 메모리에 액세스하는 것으로, 정의되지 않은 동작입니다.

배열을 다시 반복하고 지정된 메모리에 대해 malloc만큼의 여유 공간을 확보한 다음 포인터 배열을 해제해야 합니다.

for (i = 0; i < m; i++) { 
      free (a[i]);
}
free (a);

할당 연산자를 정확히 반대 순서로 작성하고 함수 이름을 변경하면 괜찮을 것입니다.

  //Free the arrays
  for (i = m-1; i >= 0; i--) { 
      free(a[i]);
  }

  free(a);

물론 동일한 역순으로 할당을 해제할 필요는 없습니다.할당된 메모리에 대한 포인터를 "잊어버리지" 않고 동일한 메모리를 한 번만 확보하는 것을 추적하기만 하면 됩니다.a例째) 것은 를 다루기 의 좋은 입니다.그러나 역순으로 할당 해제하는 것은 후자를 해결하기 위한 경험의 좋은 역할입니다.

댓글에서 libb가 지적한 것처럼, 할당/할당 해제에 부작용이 있는 경우(예:new/deleteC++의 연산자), 때로는 할당 해제의 역순이 이 특정 예제보다 더 중요할 수 있습니다.

나는 malloc()와 free()에 한 번만 전화할 것입니다.

#include <stdlib.h>
#include <stdio.h> 

int main(void){
  int i, m = 5, n = 20;
  int **a = malloc( m*(sizeof(int*) + n*sizeof(int)) );

  //Initialize the arrays
  for( a[0]=(int*)a+m, i=1; i<m; i++ ) a[i]=a[i-1]+n;

  //...do something with arrays

  //How do I free the **a ?
  free(a);

  return 0;
}

언급URL : https://stackoverflow.com/questions/1733881/c-correctly-freeing-memory-of-a-multi-dimensional-array