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
상심한long
s 또는 당신의 배열에 있는 것 대신에.int
s, 또는 나중에 다른 곳에서 사용할 수 있도록 이 코드를 수정하면 남은 참조 하나만 변경해야 합니다.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
/delete
C++의 연산자), 때로는 할당 해제의 역순이 이 특정 예제보다 더 중요할 수 있습니다.
나는 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
'programing' 카테고리의 다른 글
두 개의 RMarkdown(.Rmd) 파일을 단일 출력으로 결합하는 방법은 무엇입니까? (0) | 2023.06.14 |
---|---|
C/C++ 라이브러리를 여러 클라이언트 언어로 사용할 수 있도록 설계하는 방법은 무엇입니까? (0) | 2023.06.14 |
varchar SQL 개발자에서 선행 0을 제거하는 중 (0) | 2023.06.09 |
HTML 템플릿에서 사용하기 전에 계산된 속성에서 게터를 어떻게 조작합니까? (0) | 2023.06.09 |
왜 이 숫자들은 같지 않습니까? (0) | 2023.06.09 |