정적 메모리 할당과 동적 메모리 할당의 차이점이 무엇인지 알고 싶습니다.
예를 들어 설명해 주시겠습니까?
답변:
할당에는 정적, 자동 및 동적의 세 가지 유형이 있습니다.
정적 할당 은 프로그램이 시작될 때 변수에 대한 메모리가 할당 됨을 의미합니다. 크기는 프로그램이 생성 될 때 고정됩니다. 전역 변수, 파일 범위 변수 및 static
정의 된 내부 함수 로 한정된 변수에 적용됩니다 .
자동 메모리 할당 은 함수 내부에 정의 된 (비 정적) 변수에 대해 발생하며 일반적으로 스택에 저장됩니다 (C 표준은 스택 사용을 요구하지 않음). 이를 사용하여 추가 메모리를 예약 할 필요는 없지만 다른 한편으로이 메모리의 수명에 대한 제어가 제한됩니다. 예 : 함수의 자동 변수는 함수가 완료 될 때까지만 존재합니다.
void func() {
int i; /* `i` only exists during `func` */
}
동적 메모리 할당 은 약간 다릅니다. 이제 이러한 메모리 위치의 정확한 크기와 수명을 제어합니다. 해제하지 않으면 메모리 누수가 발생하여 특정 시점에서 시스템이 더 많은 메모리를 할당 할 수 없기 때문에 응용 프로그램이 중단 될 수 있습니다.
int* func() {
int* mem = malloc(1024);
return mem;
}
int* mem = func(); /* still accessible */
위의 예에서 할당 된 메모리는 함수가 종료 된 경우에도 여전히 유효하고 액세스 할 수 있습니다. 메모리 사용이 끝나면 해제해야합니다.
free(mem);
이것은 표준 인터뷰 질문입니다.
calloc()
, malloc()
및 친구를 사용하여 런타임에 할당 된 메모리 입니다. 힙 데이터 구조 ref 와 관련이 없지만 '힙'메모리라고도합니다 .
int * a = malloc(sizeof(int));
힙 메모리는를 free()
호출 할 때까지 지속 됩니다. 즉, 변수의 수명을 제어합니다.
이것은 일반적으로 '스택'메모리로 알려져 있으며, 새 범위를 입력 할 때 할당됩니다 (일반적으로 새 함수가 호출 스택에 푸시 될 때). 범위를 벗어나면 자동 메모리 주소의 값이 정의되지 않으며 액세스하는 것은 오류 입니다.
int a = 43;
범위가 반드시 기능을 의미하는 것은 아닙니다. 범위는 함수 내에 중첩 될 수 있으며 변수는 선언 된 블록 내에서만 범위 내에 있습니다. 이 메모리가 할당되는 위치는 지정되지 않았습니다. ( 정상적인 시스템에서는 스택에 있거나 최적화를 위해 등록됩니다)
컴파일 타임 *에 할당되며 정적 메모리에있는 변수의 수명은 프로그램 의 수명입니다 .
C에서는 static
키워드를 사용하여 정적 메모리를 할당 할 수 있습니다 . 범위는 컴파일 단위입니다.
키워드를 고려 하면extern
상황이 더 흥미로워 집니다 . 때 extern
변수가된다 정의 그것을위한 컴파일러 메모리를 할당한다. 때 extern
변수가됩니다 선언 , 컴파일러는 변수가 될 것을 요구 정의 곳. extern
변수 선언 / 정의에 실패 하면 연결 문제가 발생 하고 변수 선언 / 정의에 실패 static
하면 컴파일 문제가 발생합니다.
파일 범위에서 static 키워드는 선택적입니다 (함수 외부) :
int a = 32;
그러나 함수 범위에는 포함되지 않습니다 (함수 내부) :
static int a = 32;
기술적 extern
및 static
C. 변수의 두 개의 클래스는
extern int a; /* Declaration */
int a; /* Definition */
정적 메모리가 컴파일 타임에 할당된다고 말하는 것은 다소 혼란 스럽습니다. 특히 컴파일 머신과 호스트 머신이 동일하지 않거나 동일한 아키텍처에 있지 않을 수 있다는 점을 고려하기 시작하면 더욱 그렇습니다.
정적 메모리 할당은 컴파일 타임에 할당되는 것보다 컴파일러에 의해 처리된다고 생각 하는 것이 좋습니다 .
예를 들어 컴파일러는 data
컴파일 된 바이너리에 큰 섹션을 만들 수 있으며 프로그램이 메모리에로드되면data
프로그램의 세그먼트는 할당 된 메모리의 위치로 사용됩니다. 이것은 많은 정적 메모리를 사용하는 경우 컴파일 된 바이너리를 매우 크게 만드는 현저한 단점이 있습니다. 6 줄 미만의 코드에서 생성 된 수 기가 바이트 바이너리를 작성할 수 있습니다. 또 다른 옵션은 컴파일러가 프로그램이 실행되기 전에 다른 방식으로 메모리를 할당하는 초기화 코드를 삽입하는 것입니다. 이 코드는 대상 플랫폼 및 OS에 따라 다릅니다. 실제로 최신 컴파일러는 휴리스틱을 사용하여 이러한 옵션 중 사용할 옵션을 결정합니다. 10k, 1m, 10m, 100m, 1G 또는 10G 항목의 큰 정적 배열을 할당하는 작은 C 프로그램을 작성하여 직접 시도 할 수 있습니다. 많은 컴파일러의 경우 이진 크기는 배열 크기에 따라 선형 적으로 증가하고 특정 지점을 지나면
마지막 메모리 클래스는 '등록'변수입니다. 예상대로 레지스터 변수는 CPU 레지스터에 할당되어야하지만 결정은 실제로 컴파일러에게 맡겨집니다. address-of를 사용하여 레지스터 변수를 참조로 바꿀 수 없습니다.
register int meaning = 42;
printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */
대부분의 현대 컴파일러는 레지스터에 넣어야하는 변수를 선택하는 것보다 더 똑똑합니다. :)
int * a = malloc(sizeof(*a));
대신 유형을 반복하지 않으려면 a
. 이렇게하면 a
변경 유형이 훨씬 더 쉬워집니다 .
정적 메모리 할당 : 컴파일러는 선언 된 변수에 필요한 메모리 공간을 할당합니다. 연산자의 주소를 사용하여 예약 된 주소를 획득하고이 주소를 포인터 변수에 할당 할 수 있습니다. 선언 된 변수의 대부분은 정적 메모리를 가지고 있으므로 포인터 값을 포인터 변수에 할당하는 방법을 정적 메모리 할당이라고합니다. 메모리는 컴파일 시간 동안 할당됩니다.
동적 메모리 할당 : malloc () 또는 calloc ()과 같은 함수를 사용하여 메모리를 동적으로 가져옵니다. 이러한 함수를 사용하여 메모리를 동적으로 가져오고 이러한 함수에서 반환 된 값이 포인터 변수에 할당 된 경우 이러한 할당을 동적 메모리라고합니다. assignment.memory는 런타임 동안 어시스트됩니다.
정적 메모리 할당 :
동적 메모리 할당 :
정적 메모리 할당 과 동적 메모리 할당의 차이점
프로그램 실행이 시작되기 전에 메모리가 할당됩니다 (컴파일 중).
프로그램 실행 중에 메모리가 할당됩니다.
실행 중에는 메모리 할당 또는 할당 해제 작업이 수행되지 않습니다.
메모리 바인딩은 실행 중에 설정되고 삭제됩니다.
변수는 영구적으로 할당 된 상태로 유지됩니다.
프로그램 단위가 활성화 된 경우에만 할당됩니다.
스택 및 힙을 사용하여 구현됩니다.
데이터 세그먼트를 사용하여 구현됩니다.
변수에 액세스하려면 포인터가 필요합니다.
동적으로 할당 된 포인터가 필요하지 않습니다.
Dynamic보다 빠른 실행.
정적보다 실행 속도가 느립니다.
더 많은 메모리 공간이 필요합니다.
적은 메모리 공간이 필요합니다.
정적 메모리 할당은 컴파일 시간 동안 pf 프로그램을 실행하기 전에 메모리가 할당됩니다. 동적 메모리 할당은 런타임에 프로그램을 실행하는 동안 할당 된 메모리입니다.