stack - memory-management - Heap memory 란 - 스택과 힙은 무엇이며 어디에 있습니까?

자바 메모리 구조 / memory-management / language-agnostic / heap / dynamic-memory-allocation

프로그래밍 언어 책 에서는이 두 가지가 무엇인지 설명하지 않고 값 유형이 스택에 생성 되고 참조 유형이 에 생성된다고 설명합니다 . 나는 이것에 대한 명확한 설명을 읽지 못했습니다. 나는 스택 이 무엇인지 이해합니다 . 그러나,

RajeshKdev



Answer #1

이 모든 것을 설명하기 위해 간단한 주석이 달린 C 코드를 제공 할 것입니다. 배우는 가장 좋은 방법은 디버거에서 프로그램을 실행하고 동작을 관찰하는 것입니다. 파이썬을 읽고 싶다면 대답의 끝으로 건너 뛰십시오 :)

// 프로그램 / DLL이 처음로드 될 때 데이터 세그먼트에 정적으로 할당됩니다.
// 프로그램 / DLL이 종료되면 할당 해제 됨
// 범위-코드의 어느 곳에서나 액세스 가능
int someGlobalVariable;

// 프로그램이 처음로드 될 때 데이터 세그먼트에 정적으로 할당 됨
// 프로그램 / DLL이 종료되면 할당 해제 됨
// 범위-이 특정 코드 파일의 어느 곳에서나 액세스 할 수 있습니다.
static int someStaticVariable;

// MyFunction이 호출 될 때마다 "someArgument"가 스택에 할당됩니다.
// MyFunction이 반환하면 "someArgument"가 할당 해제됩니다.
// 범위-MyFunction () 내에서만 액세스 할 수 있습니다.
void MyFunction(int someArgument) {

    // 프로그램이 처음로드 될 때 데이터 세그먼트에 정적으로 할당 됨
    // 프로그램 / DLL이 종료되면 할당 해제 됨
    // 범위-MyFunction () 내에서만 액세스 할 수 있습니다.
    static int someLocalStaticVariable;

    // MyFunction이 호출 될 때마다 스택에 할당됩니다.
    // MyFunction이 반환되면 할당 해제 됨
    // 범위-MyFunction () 내에서만 액세스 할 수 있습니다.
    int someLocalVariable;

    // MyFunction이 호출 될 때마다 스택에 * pointer *가 할당됩니다.
    //이 포인터는 MyFunction이 반환 할 때 할당 해제됩니다.
    // 범위-포인터는 MyFunction () 내에서만 액세스 할 수 있습니다.
    int* someDynamicVariable;

    //이 줄은 힙에 정수를위한 공간을 할당합니다.
    //이 라인이 실행될 때. 이것은 시작 부분이 아닙니다.
    // 자동 변수와 같은 MyFunction () 호출
    // 범위-MyFunction () 내의 코드 만이 공간에 액세스 할 수 있습니다.
    // *이 특정 변수를 통해 *.
    // 그러나 주소를 다른 곳에 전달하면 해당 코드
    // 액세스 가능
    someDynamicVariable = new int;


    //이 줄은 힙의 정수 공간을 할당 해제합니다.
    // 작성하지 않으면 메모리가 "누수"됩니다.
    // 스택과 힙의 근본적인 차이점에 유의하십시오.
    // 힙을 관리해야합니다. 스택은 우리를 위해 관리됩니다.
    delete someDynamicVariable;

    // 다른 경우에는이 힙 공간을 할당 해제하는 대신
    // 나중에 사용하기 위해 주소를 더 영구적 인 위치에 저장할 수 있습니다.
    // 일부 언어는 할당 해제도 처리하지만 ...
    // 항상 어떤 메커니즘에 의해 런타임에 처리되어야합니다.

    // 함수가 반환되면 someArgument, someLocalVariable
    // 포인터 someDynamicVariable이 할당 해제됩니다.
    // someDynamicVariable이 가리키는 공간은 이미
    // 반환하기 전에 할당 해제됩니다.
    return;
}

// someGlobalVariable, someStaticVariable 및
// someLocalStaticVariable은 계속 존재하지만
// 프로그램이 종료 될 때까지 할당 해제됩니다.

C / C ++의 일부 구문 선택은이 문제를 악화시킵니다. 예를 들어 많은 사람들은 아래에 표시된 구문 때문에 전역 변수가 "정적"이 아니라고 생각합니다.

int var1; // 전역 범위와 정적 할당이 있습니다.
static int var2; // 파일 범위와 정적 할당이 있습니다.

int main() {return 0;}

어떤 사람들은 이러한 개념을 C / C ++ 특정이라고 생각합니다. 그렇지 않습니다. 예를 들어, 아래의 Python 샘플은 세 가지 유형의 할당을 모두 보여줍니다 (여기서는 다루지 않겠지 만 해석 언어에는 미묘한 차이가있을 수 있습니다).

from datetime import datetime

class Animal:
    _FavoriteFood = 'Undefined' # _FavoriteFood는 정적으로 할당됩니다.

    def PetAnimal(self):
        curTime = datetime.time(datetime.now()) # curTime은 자동으로 할당됩니다.
        print("Thank you for petting me. But it's " + str(curTime) + ", you should feed me. My favorite food is " + self._FavoriteFood)

class Cat(Animal):
    _FavoriteFood = 'tuna' # 우리가 재정의했기 때문에 Cat 클래스에는 Animal의 것과는 다른 정적으로 할당 된 _FavoriteFood 변수가 있습니다.

class Dog(Animal):
    _FavoriteFood = 'steak' # 마찬가지로 Dog 클래스는 자체 정적 변수를 가져옵니다. 중요한 점은이 정적 변수는 Dog의 모든 인스턴스간에 공유되므로 동적이 아닙니다!


if __name__ == "__main__":
    whiskers = Cat() # 동적 할당
    fido = Dog() # 동적 할당
    rinTinTin = Dog() # 동적 할당

    whiskers.PetAnimal()
    fido.PetAnimal()
    rinTinTin.PetAnimal()

    Dog._FavoriteFood = 'milkbones'
    whiskers.PetAnimal()
    fido.PetAnimal()
    rinTinTin.PetAnimal()

# 출력은 다음과 같습니다.
# 귀여워 줘서 고마워. 하지만 그것은 13 : 05 : 02.255000입니다. 내가 제일 좋아하는 음식은 참치
# 귀여워 줘서 고마워. 하지만 그것은 13 : 05 : 02.255000입니다. 내가 제일 좋아하는 음식은 스테이크
# 귀여워 줘서 고마워. 하지만 그것은 13 : 05 : 02.255000입니다. 내가 제일 좋아하는 음식은 스테이크
# 귀여워 줘서 고마워. 하지만 그것은 13 : 05 : 02.255000입니다. 내가 제일 좋아하는 음식은 참치
# 귀여워 줘서 고마워. 하지만 그것은 13 : 05 : 02.255000입니다. 내가 제일 좋아하는 음식은 밀크 본
# 귀여워 줘서 고마워. 하지만 그것은 13 : 05 : 02.256000입니다. 내가 제일 좋아하는 음식은 밀크 본