다시 오신 걸 환영해요 이번 강의에서는 동적 메모리 분배에 관해 얘기할게요
이건 포인터와 직접 관련 있어요 포인터에서만 사용할
수 있죠 그럼 시작하죠
C#에서 변수를 정의할 때마다
컴파일러는 데이터 유형에 기반하여 자동으로 올바른 양의 저장소를 할당하죠
줄곧 봐왔던 거죠 정수, 부동 소수점, 더블을 만들 때 메모리를 할당할 필요가 없어요
컴파일러가 다 하죠 일부 메모리를 할당하죠
조언도 마찬가지일 거예요 포인터를 생성하면 메모리가
할당되고 포인터 타입과 주소를 저장하죠
그 말은 메모리가 해당 주소를 위해 할당된다는 건 아니에요
여기까지는 데이터를 포인터에 할당할 때마다
항상 기존 변수를 할당해왔죠
데이터를 포인터에 할당하고
싶다면 이미 할당된 메모리가 있는 변수에서 연산자의
& 앰퍼 주소를 사용하면 되는 것이죠
그런데 만약 포인터를 생성하고 싶고 연산자의 주소를 할당하고 싶지 않다면 어떨까요?
동적으로 메모리를 할당하고 싶다면요? 이 강의의 목적이 그거잖아요
그래서 프로그램이 실행되는 동안 스토리지를 동적으로 할당할
수 있는 것이 바람직하죠 필요한 만큼 메모리를 할당하세요
파일에서 메모리 배열로 데이터 세트를 읽도록 설계된
프로그램이 있다면 세 가지 선택이 있어요
컴파일할 수 있는 가능한 요소의 최대치를 포함하는 배열을 정의할 수
있어요 고정된 크기죠
50개의 요소를 가진 배열을 정의하면 50개
요소만 포함하게 되죠 컴파일러가 50이라고 결정하고 실행될
때 그만큼의 메모리를 할당할 것이죠
길이 배열을 이용해 배열 런타임의 크기에 맞출 수 있어요
길이 변수 배열에 관해 잠깐 얘기했죠
C11까지는 지원 안 돼요 C11을 들어내고 C99를 추가했어요
여기에 변수를 넣을 수 있어요
하지만 여전히 고정된 크기죠 그건 변수
링크 배열이 크기를 위한 변수를 통과시킬 수 있다는 뜻이니까요
하지만 여전히 정지해 있죠
가장 좋은 선택은 필요한 대로 배열을 동적으로 할당하는 거죠
이 작업을 위해 호출할 수 있는 다양한 c 함수들이 있어요
따라서 메모리를 동적으로 할당하는 데 아주 유용하죠
그래서 지금까지 계속 해온 첫 번째 접근법으로 배열이든
데이터 유형이든 고정된 크기죠
그 배열에 들어갈 최대 요소들을 포함하기 위해 여러분의
배열을 정의해야 해요
그래서 이런 걸 하는 거죠
데이터 파일에 1천 개 이상의 요소를 포함할 수 없다는 뜻이죠
그렇게 되면 프로그램이 망가질 거예요
우리가 읽는 파일이 어떤 것이든 데이터가 많지 않기를 바랄 뿐이죠
여러분의 프로그램은 큰 세트의 파일이나 큰 파일로는 작동하지 않아요
큰 파일로 작업하고 싶다면 돌아가서 배열을 크게 만들어야 해요
크기도 바꿔야 하고
재편집도 해야 하죠 컴파일 타임이에요
어떤 값을 선택하든 미래에 같은 문제에 다시
부딪힐 가능성이 있어요 고정된 크기니까요
이 크기는 코드를 컴파일할 때 결정되죠
프로그램을 실행할 때 조정되지 않아요
동적으로 변하지 않아요
동적 메모리 할당 함수를 사용하면 필요한 스토리지를 얻을 수 있죠
이렇게 하면 프로그램이 실행될 때 메모리를 할당할 수 있죠
그러니 장점을 생각해 보세요 첫째, 사용하지 않는
엄청나게 많은 메모리를 생성하지
않아도 돼요 필요한 만큼만 생성하세요
더 필요하면 더 할당하면 되고요
재편집하거나 크기를 바꿀 필요가 없어요
동적 메모리 할당도 좋은 방법이죠
포인터의 개념에 따라 다르고 코드에서 포인터를
사용하도록 강력한 인센티브를 제공하죠
포인터의 이점에 대해 얘기했었는데요 여러분은
아마 멋진 개념이긴 하지만 왜 포인터를 사용해야 하는지 생각하셨을
겁니다 큰 이유 중 하나인데요
메모리를 동적으로 할당할 수 있기 때문이죠
그럼 C는 뭐죠? 효율적인 언어예요 메모리를
많이 쓰지 않는 거죠
C#은 임베디드 시스템과 실시간 프로그래밍으로
돌아가죠 이게 그 이유 중 하나예요 필요에 따라 메모리를
제한할 수 있거든요
동적 메모리 할당은 프로그램이 실행될 때 메모리를 동적으로 할당하도록
저장하죠
메모리를 동적으로 할당할 수 있는 건 여러분이 포인터를
사용할 수 있기 때문이죠
주소가 있기 때문에 포인터가 가리키는
양을 바꿀 수 있어요 메모리를 재조정할 수 있죠
대부분의 제작 프로그램은 동적 메모리 할당을 사용하죠
C#에서 코드를 작성한다면 이걸 사용해야죠
초보자라도 동적 메모리 할당은
사용할 수 있죠 대부분의 유용한 프로그램이 이 개념을 이용할 거예요
데이터를 동적으로 할당하면 런타임에 포인터를 생성해
작업에 필요한 데이터를 저장할 수 있습니다 메모리를
낭비하지 않죠 활력이 넘쳐요
힙 대 스택에 대해서도 이야기해야 하는데요
프로그램에서 메모리를 저장하는 데는 두 가지 방법이 있습니다. 두
가지 다른 데이터 구조가 있고 스택에 데이터를 저장할 수도 있고 힙에 데이터를 저장할
수도 있죠.
동적 메모리 할당은 모든 걸 저장하죠
어떻게 조직되었는지 상세히 살펴보진 않겠습니다만 본질적으로요
힙에 데이터를 저장하면 더 많은 변화가
가능하죠
임의로 데이터 개체 크기를 변경할 수 있어요 메모리를
힙에 할당할 때 훨씬 더 오래 머물죠 프로그램
전체에 머물러요
스택을 사용하면 더 제한적이죠
스택은 함수 인수부터 로컬 변수까지 모든 것에 사용되죠
거기에 모든 게 저장돼 있어요
그래서 콜 스택에 관해 얘기한 거예요
메서드와 함수를
봤죠 가끔 메서드를 쓰지만 메서드는 객체 지향 용어라서
함수를 쓰죠
함수와 관련된 모든 것은 스택에서 생성되죠
무슨 뜻이냐면 함수를 실행하면
스택에 올라간다는 거죠 지역 변수가 스택에 올라가죠
기능을 종료하면 모든 게 삭제돼요
스택에 위치한 메모리는 오래 머물지 않아요
그게 메모리를 동적으로 할당할 때 힙에 있는 이유
중 하나입니다 사용할
때는 컨트롤을 하고 사용하지 않을 때는 할당하고 삭제하기 때문이죠
저장소에 있는 건 조종할 수 없어요 자동으로 삭제되고
자동으로 할당되죠
그러니까 로컬 변수 메인 같은 함수 내의 변수는
스택 등에서 생성되는 거죠
힙의 메모리는 다릅니다 프로그래머인 당신이 제어하죠
메모리를 힙에 할당할 때 메모리가 언제 할당되는지 추적하는 것은 여러분에게 달렸습니다 할당된 것은
더 이상 필요하지 않습니다 그래서 여러분은 메모리를 삭제해야 하죠
더 이상 사용하지 않는
공간을 비워줘야 해요 기억력은 매우 희귀한
자원이기 때문에 아주 중요해요
오늘날엔 컴퓨터를 돌릴 수 있는 메모리가 많아요 12기가,
16기가 등이죠 하지만 장치에서
실행되는 프로그램은 메모리가
그리 많지 않아요 메모리 사용량을 제어해야
하고 사용이 끝나면 메모리를 방출해야 다른 앱이
사용할 수 있죠
하위레벨 내장 유형 시스템에선 더 중요해요
하지만 많은 언어가 누릴 수 없는 자유죠 프로그래머에 의해 관리자의
메모리를 제어하는 기능으로 프로그램을 훨씬
효율적이고 빠르게 만들 수 있죠
다음 강의에서는 실제로 어떻게 하는지 어떤 기능을
호출할 수 있는지 알아보죠 사용하지 않는 메모리를 할당하기 위해
호출할 수 있는 다양한 함수들이 있죠 고마워요