C++ Chapter 6.10 : 메모리 동적 할당 new와 delete
카테고리: Cpp
태그: Cpp Programming
인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!
동적 메모리 할당이란?
- 필요할 때만 메모리를 할당받아서 사용하고 반납할 수 있다.
- 지역변수나 배열은
{}
를 벗어나면 메모리에서 사라지므로 여러 함수에서 사용하기에 부적합하다. - 전역 변수나 배열은 여러 함수에서 사용할 수 있지만 프로그램의 시작부터 종료까지 메모리를 점유하므로 공간을 비효율적으로 사용하게 됨
- 이에 반하여 동적으로 메모리를 할당 받으면 내가 필요할 때
{}
범위에 구애받지 않고 사용하고 원하는 기간동안 사용 후 메모리를 반납할 수 있다.
- 지역변수나 배열은
- 실행 중에 사용될 메모리 양을 컴파일 타임에 미리 예측하기가 힘들 때
- 정적 배열같은 경우 배열의 크기를 미리 컴파일 타임때 알고 있어야 메모리를 할당 받을 수 있는데 그렇기 때문에 일부러 배열 크기를 미리 크게, 넉넉하게 할당받고 실행하는 경우가 많다. 공간 낭비.
- 동적 할당 받은 배열의 경우 크기를 실행중에 결정할 수 있다.
- 동적 메모리 할당을 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 초기화 해주어야 함- 수동으로 다 해주기엔 쉬운 일이 아니다 😰 이때 도움 되는 기능이 바로
스마트 포인터
. 15챕터에서 배움.
- 수동으로 다 해주기엔 쉬운 일이 아니다 😰 이때 도움 되는 기능이 바로
답변 작성하면서 나도 처음 알게 된 부분이었다. 힙 메모리를 할당 받을 때부터 해당 주소에 얼마만큼의 크기를 할당 받았었는지를 내부적으로 이미 기억하고 있기 때문에 delete
에 해당 힙 메모리 주소만 딱 넘겨주면 딱 할당받았었던 만큼의 크기를 해제할 수 있었던 것이다. https://stackoverflow.com/questions/197675/how-does-delete-know-the-size-of-the-operand-array
메모리 누수 memory leak
while (true)
{
int * ptr = new int;
cout << ptr << endl;
}
다음 반복 때 기존의 while의 지역변수 ptr은 사라지고 새로운 ptr이 선언되기 때문에 기존 ptr에 할당 되어 있던 기존의 new int 영역은 미아가 되버린다! 주소를 잃어버려 찾을 길 없이 그냥 공간만 차지하고 있는 가비지가 되는 것이다. 이게 쌓이고 쌓이면 메모리 누수 문제가 발생한다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기