본문 바로가기
C │ C++ │ C#/C++

C++ Chapter 6.10 : 메모리 동적 할당 new와 delete

by Pokaa 2023. 11. 5.
728x90
728x90
SMALL
동적 메모리 할당이란?

 

  1. 필요할 때만 메모리를 할당받아서 사용하고 반납할 수 있다.
    ο  지역변수나 배열은  { } 를 벗어나면 메모리에서 사라지므로 여러 함수에서 사용하기에 부적합하다.
    ο  전역 변수나 배열은 여러 함수에서 사용할 수 있지만 프로그램의 시작부터 종료까지 메모리를 
       점유하므로 공간을 비효율적으로 사용하게 됨
    ο  이에 반하여 동적으로 메모리를 할당 받으면 내가 필요할 때  { }  범위에 구애받지 않고
       사용하고 원하는 기간동안 사용 후 메모리를 반납할 수 있다.
  2. 실행 중에 사용될 메모리 양을 컴파일 타임에 미리 예측하기가 힘들 때
    ο  정적 배열같은 경우 배열의 크기를 미리 컴파일 타임때 알고 있어야 메모리를 할당 받을 수 있는데 
       그렇기 때문에 일부러 배열 크기를 미리 크게, 넉넉하게 할당받고 실행하는 경우가 많다. 공간 낭비.
    ο  동적 할당 받은 배열의 경우 크기를 실행중에 결정할 수 있다.
  3. 동적 메모리 할당을 OS에 요청하면  힙 메모리 중 사용중이 아닌 영역을 OS가 할당해준다.
    ο  정적 할당은  스택 메모리 에 할당되는데 힙 메모리가 스택 메모리보다 크기가 훨씬 크다!
  4. 다만 실행 중에 할당 받으므로 시간 지연이 발생하며 성능 저하가 있을 수 있다.
    ο  정적 할당은 프로그램이 실행되기 전에 컴파일 타임때 미리 할당받은 공간을 그대로 
       사용하는 것이기 때문에 시간 지연이 없다.
  5. 프로그래머가 수동적으로 직접 메모리를 해제, 반납 해주어야 한다.
    ο  까먹으면 메모리 누수 발생 가능.
    ο  메모리를 동적으로 할당받아 사용한 후 해제 하지 않는 것.
  6. 기본적으로는  자동 할당 이나  정적 할당 을 사용하고 일시적으로 쓰거나 실행 중에 결정되는 정보에
     필요한 메모리는  동적 할당 을 사용하면 된다.

 

 

동적으로 메모리 할당 받기 : 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