728x90
728x90
SMALL
동적 메모리 할당이란?
- 필요할 때만 메모리를 할당받아서 사용하고 반납할 수 있다.
ο 지역변수나 배열은 { } 를 벗어나면 메모리에서 사라지므로 여러 함수에서 사용하기에 부적합하다.
ο 전역 변수나 배열은 여러 함수에서 사용할 수 있지만 프로그램의 시작부터 종료까지 메모리를
점유하므로 공간을 비효율적으로 사용하게 됨
ο 이에 반하여 동적으로 메모리를 할당 받으면 내가 필요할 때 { } 범위에 구애받지 않고
사용하고 원하는 기간동안 사용 후 메모리를 반납할 수 있다. - 실행 중에 사용될 메모리 양을 컴파일 타임에 미리 예측하기가 힘들 때
ο 정적 배열같은 경우 배열의 크기를 미리 컴파일 타임때 알고 있어야 메모리를 할당 받을 수 있는데
그렇기 때문에 일부러 배열 크기를 미리 크게, 넉넉하게 할당받고 실행하는 경우가 많다. 공간 낭비.
ο 동적 할당 받은 배열의 경우 크기를 실행중에 결정할 수 있다. - 동적 메모리 할당을 OS에 요청하면 힙 메모리 중 사용중이 아닌 영역을 OS가 할당해준다.
ο 정적 할당은 스택 메모리 에 할당되는데 힙 메모리가 스택 메모리보다 크기가 훨씬 크다! - 다만 실행 중에 할당 받으므로 시간 지연이 발생하며 성능 저하가 있을 수 있다.
ο 정적 할당은 프로그램이 실행되기 전에 컴파일 타임때 미리 할당받은 공간을 그대로
사용하는 것이기 때문에 시간 지연이 없다. - 프로그래머가 수동적으로 직접 메모리를 해제, 반납 해주어야 한다.
ο 까먹으면 메모리 누수 발생 가능.
ο 메모리를 동적으로 할당받아 사용한 후 해제 하지 않는 것. - 기본적으로는 자동 할당 이나 정적 할당 을 사용하고 일시적으로 쓰거나 실행 중에 결정되는 정보에
필요한 메모리는 동적 할당 을 사용하면 된다.
동적으로 메모리 할당 받기 : new
new 는 C++ 의 연산자 중 하나이다.
int * ptr = new int;
*ptr = 7;
/*
이는 곧
int var;
var = 7; 과 같다.
*/
new + 데이터타입 : 해당 데이터 타입의 크키만큼 힙 메모리를 할당 받아온 후 주소를 리턴한다.
- ptr 포인터에 int 1개의 크기만큼 할당된 힙 메모리 공간의 주소를 저장한다.
동적으로 할당받은 메모리 반납하기 : delete
delete 또한 C++ 의 연산자 중 하나이다.
int * ptr = new int;
int * ptr2 = ptr;
delete ptr;
delete 포인터 : 해당 포인터가 가리키고 있는 힙 메모리 영역을 반납한다.
- ptr : ptr 값은 변함 없다. 주소값은 변함없다.
- *ptr : 그러나 ptr이 가리키고 있는 데이터 값은 쓰레기 값이 들어가있게 된다.
ptr이 가리키는 영역이 지워진 것이기 때문에 간접 참조 할 수 없게 된다.
ο 마치 주소는 변치 않고 집만 비워지는 꼴
ο 따라서 delete 해준 후에는 ptr = nullptr Null포인터로 초기화 해주는 습관을 들이자.
아무 영역도 가리키지 않도록.
ο int * ptr2 = ptr; 로 인하여 ptr2 도 ptr과 같은 곳을 가리키고 있었으니 ptr2로 간접참조 하면 쓰레기 값이
나오게 된다. ptr2도 nullptr 초기화 해주어야 함
□ 수동으로 다 해주기엔 쉬운 일이 아니다 😰 이때 도움 되는 기능이 바로 스마트 포인터 .
힙 메모리를 할당 받을 때부터 해당 주소에 얼마만큼의 크기를 할당 받았었는지를 내부적으로 이미 기억하고 있기 때문에 delete 에 해당 힙 메모리 주소만 딱 넘겨주면 딱 할당받았었던 만큼의 크기를 해제할 수 있었던 것이다.
메모리 누수 memory leak
while (true)
{
int * ptr = new int;
cout << ptr << endl;
}
다음 반복 때 기존의 while의 지역변수 ptr은 사라지고 새로운 ptr이 선언되기 때문에 기존 ptr에 할당 되어 있던 기존의 new int 영역은 미아가 되버린다!
주소를 잃어버려 찾을 길 없이 그냥 공간만 차지하고 있는 가비지가 되는 것이다.
이게 쌓이고 쌓이면 메모리 누수 문제가 발생한다.
728x90
300x250
LIST
'C │ C++ │ C# > C++' 카테고리의 다른 글
C++ Chapter 6.12 : 포인터와 const (1) | 2023.11.19 |
---|---|
C++ Chapter 6.11 : 동적 할당 배열 (1) | 2023.11.12 |
C++ Chapter 6.9 : C언어 스타일의 문자열 기호적 상수 (1) | 2023.10.29 |
C++ Chapter 6.8 : 포인터의 연산과 배열 인덱싱 (2) | 2023.10.15 |
C++ Chapter 6.7 : 포인터와 정적 배열 (0) | 2023.09.28 |