동적 할당 메모리

A Code AM·2020년 3월 6일
0

모르고 썼다

목록 보기
3/7
post-thumbnail

동적 메모리 할당(Dynamic memory allocation)

: 프로그램이 실행 도중에 히프에서 동적으로 메모리를 할당 받는 것
-> 필요한 때에 필요한 만큼만 할당 받을 수 있어 메모리를 효율적으로 사용할 수 있음.

히프(Heap) : 컴퓨터에서 아직 사용하지 않은 메모리 공간

동적 할당의 단계

  1. 얼마나 할당 받을 것인지 결정
  2. 라이브러리 함수 호출
  3. 운영 체제에게 메모리를 요청
  4. 충분한 메모리가 존재하면 승인되고 메모리 할당
  5. 할당된 메모리 사용하여 작업
  6. 사용이 끝나면 메모리를 다시 운영체제에게 반납 (반납하지 않으면 동적 메모리를 다른 프로그램이 사용하지 못한다 > 반드시 명시적으로 반납 해주어야 함)

동적 메모리는 포인터 말고는 접근할 수 있는 방법이 없다.

new 연산자 - 동적 메모리 할당

p(포인터) = new 동적메모리 타입[동적메모리 개수] {동적 메모리 초기값들 ...};

p가 가리키는 첫번째 변수는 p[0] / p로 접근 할 수 있다.
p가 가리키는 두번째 변수는 p[1] /
(p+1)로 접근 할 수 있다.

Q. 정적배열과 동적배열의 차이?
A. 정적배열은 컴파일 시에 크기가 결정되어야 함. 동적배열은 new에 의해 생성되고 그 크기를 변경할 수 있다. 그리고 컴퓨터 시스템에 의하여 히프 메모리 영역에 할당된다. 항상 요청이 만족되지는 않는다 > 메모리가 없으면 bad_alloc이란 오류가 발생한다.

delete 연산자 - 동적 메모리 해제

배열을 해제할 때에는 반드시 delete[]를 사용해주어야 한다.

스마트 포인터(Smart pointer)

: 포인터처럼 동작하는 클래스 템플릿. 자동으로 nullptr로 초기화 됨. 프로그래머가 동적 메모리 할당 후에 잊어버려도 자동으로 동적 메모리를 삭제해주는 기능으로 기본 포인터(raw pointer)가 실제 메모리를 가리키도록 초기화 한 후에 기본 포인터를 스마트 포인터에 대입해서 사용한다. -> 메모리를 해제해주지 않으면 메모리 누수가 일어난다.
= 객체 생성과 유사하다. (차이점 : 별도로 백그라운드에서 실행되는건 아님)
= 동적메모리는 컴파일 단계에서 모두 안전하게 처리되므로 실행될 때에는 쓰레기 수집기가 없어도 되고 실행 속도도 빨라진다.

메모리 누수(Memory leak) : 사용이 끝난 메모리를 제대로 해지하지 않아서 컴퓨터 프로그램이 필요하지 않은 메모리를 계속 점유하고 있는 현상.

unique_ptr

: 포인터에 대해 오직 하나의 소유자만 허용하며 shared_ptr이 필요하다는 점을 확실히 알지 못하는 경우에만 사용한다. 기본 포인터를 감싸서 객체로 만든다. 객체에 소멸자를 추가해서 객체가 소멸되면 포인터가 가리키는 메모리 공간도 해제한다. 새 소유자로 이동할 수 있지만 복사나 공유는 안된다. 노후된 auto_ptr을 대체함. 어떤 자료형의 포인터도 감쌀 수 있다.

shared_ptr

: 참조 횟수가 계산되는 스마트 포인터. 원시 포인터 하나를 여러 소유자에게 할당하려고 할 경우 사용 됨. 원시 포인터는 모든 shared_ptr 소유자가 범위를 벗어나거나 소유권 포기할 때까지 삭제되지 않는다.

객체 동적 생성

: 객체가 몇 개나 생성되어야 하는지 알 수 없는 경우에 사용한다.
동적으로 생성된 객체의 멤버에 접근하기 이용해서 도트 연산자를 사용하나 표기법이 번거로워서

(*pDog).getAge(); >> pDog->getAge(); 			// 이런식으로 표기함.

= 클래스의 멤버도 히프에 동적으로 생성할 수 있다. 이럴 경우엔 생성자에서 동적 할당 되어야 하고 소멸자에서 동적 메모리를 해제하여애 한다.

main()에서는 클래스 멤버 변수들이 포인터란 것을 인지하지 못한다. 메모리 관리가 전적으로 클래스의 구현 안에 감춰져 있기 때문.

profile
배움기록

0개의 댓글