정적 메모리 할당과 동적 메모리 할당의 차이점


답변:


91

할당에는 정적, 자동 및 동적의 세 가지 유형이 있습니다.

정적 할당 은 프로그램이 시작될 때 변수에 대한 메모리가 할당 됨을 의미합니다. 크기는 프로그램이 생성 될 때 고정됩니다. 전역 변수, 파일 범위 변수 및 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);

2
물론 변수의 수명을 제어 할 수 있습니다. 범위를 결정하는 사람이 바로 당신입니다.
Luchian Grigore 2011

물론 그게 내가 의미하는 바가 아닙니다. 변수의 수명을 연장하여 범위를 초과 할 수 없습니다. 그러나 아마도 나는 내 대답에서 그것을 명확히해야 할 것입니다. 감사합니다
Constantinius

5
-1이 대답은 틀 렸습니다. 정적자동 변수를 혼동 합니다.
brice 2013-04-03

2
자신의 문장은 다음과 같습니다. " 정적 할당은 변수에 대한 메모리가 자동으로 할당 됨을 의미합니다 . "이것은 잘못된 것 입니다. GNU의 libc에 대한 매뉴얼 페이지 가 그것에 대해 무엇을 말하고 있는지 살펴보십시오 .
brice 2013-04-03

1
@EliBendersky 이제 다시 표현됩니다. 지금 올바른지 확인하십시오.
Suraj Jain

116

이것은 표준 인터뷰 질문입니다.

동적 메모리 할당

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;

기술적 externstaticC. 변수의 두 개의 클래스는

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. */

대부분의 현대 컴파일러는 레지스터에 넣어야하는 변수를 선택하는 것보다 더 똑똑합니다. :)

참조 :


3
참고 : int * a = malloc(sizeof(*a));대신 유형을 반복하지 않으려면 a. 이렇게하면 a변경 유형이 훨씬 더 쉬워집니다 .
Shahbaz 2013

1
일반적으로 힙이라고하지만 힙 데이터 구조와 관련이 없습니다. 이 경우 힙 지저분한 장소 수단
동적

2
"정적 메모리 할당 ... 컴파일 타임에 할당 됨"할당 크기가 컴파일 타임에 결정 된다는 의미 입니까? 메모리 설정은 런타임에만 발생하지 않습니까?
lf215

2

정적 메모리 할당 : 컴파일러는 선언 된 변수에 필요한 메모리 공간을 할당합니다. 연산자의 주소를 사용하여 예약 된 주소를 획득하고이 주소를 포인터 변수에 할당 할 수 있습니다. 선언 된 변수의 대부분은 정적 메모리를 가지고 있으므로 포인터 값을 포인터 변수에 할당하는 방법을 정적 메모리 할당이라고합니다. 메모리는 컴파일 시간 동안 할당됩니다.

동적 메모리 할당 : malloc () 또는 calloc ()과 같은 함수를 사용하여 메모리를 동적으로 가져옵니다. 이러한 함수를 사용하여 메모리를 동적으로 가져오고 이러한 함수에서 반환 된 값이 포인터 변수에 할당 된 경우 이러한 할당을 동적 메모리라고합니다. assignment.memory는 런타임 동안 어시스트됩니다.


2

정적 메모리 할당 :

  • 변수는 영구적으로 할당됩니다.
  • 프로그램 실행 전에 할당이 수행됩니다.
  • 정적 할당을 구현하기 위해 스택 이라는 데이터 구조를 사용합니다.
  • 덜 효율적
  • 메모리 재사용없습니다.

동적 메모리 할당 :

  • 프로그램 단위가 활성화 된 경우에만 변수가 할당 됩니다.
  • 프로그램 실행 중에 할당이 수행 됩니다.
  • 동적 할당을 구현하기 위해 이라는 데이터 구조를 사용합니다.
  • 더 효율적
  • 메모리 재사용이 . 필요하지 않을 때 메모리를 해제 할 수 있습니다.

1
"정적 메모리 할당 [...] 정적 할당을 구현하기 위해 스택이라는 데이터 구조를 사용합니다." 아니요 , 이는 잘못된 것이며 오해의 소지가 있습니다. 자동 할당과 정적 할당의 차이점은 내 게시물을 참조하십시오. 정적 메모리 스택을 사용할 있습니다. 이는 구현에 따라 크게 달라지며 동일한 구현에 여러 전략을 사용할 수 있습니다. "덜 효율적"이라는 말이 무슨 뜻인지 잘 모르겠습니다. @Trieu Toan, 잘못된 편집 으로이 답변의 의미를 변경했습니다.
brice

1

정적 메모리 할당동적 메모리 할당의 차이점

프로그램 실행이 시작되기 전에 메모리가 할당됩니다 (컴파일 중).
프로그램 실행 중에 메모리가 할당됩니다.

실행 중에는 메모리 할당 또는 할당 해제 작업이 수행되지 않습니다.
메모리 바인딩은 실행 중에 설정되고 삭제됩니다.

변수는 영구적으로 할당 된 상태로 유지됩니다.
프로그램 단위가 활성화 된 경우에만 할당됩니다.

스택 및 힙을 사용하여 구현됩니다.
데이터 세그먼트를 사용하여 구현됩니다.

변수에 액세스하려면 포인터가 필요합니다.
동적으로 할당 된 포인터가 필요하지 않습니다.

Dynamic보다 빠른 실행.
정적보다 실행 속도가 느립니다.

더 많은 메모리 공간이 필요합니다.
적은 메모리 공간이 필요합니다.


1
동적 메모리 할당은 힙에 할당하는 동안 정적 메모리 할당은 스택에 할당
우스만 쿠르드족

@UsmanKurd 일반적으로 정적 메모리와 관련하여 올바르지 않습니다. 내 대답을 참조하십시오.
brice

0

정적 메모리 할당은 컴파일 시간 동안 pf 프로그램을 실행하기 전에 메모리가 할당됩니다. 동적 메모리 할당은 런타임에 프로그램을 실행하는 동안 할당 된 메모리입니다.


-1

정적 메모리 할당. 할당 된 메모리는 스택에 있습니다.

int a[10];

동적 메모리 할당. 할당 된 메모리는 힙에 있습니다.

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

C에는 GC (Garbage Collector)가 없기 때문에 후자는 자유워야합니다 .

free(a);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.