동적 할당

Oak_Cassia·2021년 11월 14일
0

malloc / free

void* malloc(size_t size)
메모리 할당 후 시작 주소를 가리키는 포인터를 반환해준다.

  • 타입에 상관없이 특정한 크기의 메모리를 할당할 수 있다.
  • size_t는 unsigned int 이다.
  • void* 어떠한 데이터 형을 저장하는지 예측할 수 없기 때문에 void*를 먼저 반환 후 개발자가 이를 변환 하여 사용한다.

void free(void* ptr)
메모리를 반환하는 함수.

어떻게 다른 정보 없이 반환을 하는지 보자.

int main()
{
	BP* b1 = (BP*)malloc(12);
	 
	b1->a = 9;
	b1->b = 10;
	b1->c = 9;
	cout << b1 << endl;
	free(b1);
}


첫 번째 줄을 보면 12가 들어 있다.
이는 int 멤버변수가 3개 있는 클래스의 객체의 크기와 같다.
메모리 청크 앞에는 이와 같은 헤더가 있는데 free가 크기를 알아낼 때 사용한다.(시스템 마다 다르다. 테이블을 보고 찾는 경우.)


new / delete

malloc /free가 함수였다면 new / delete는 연산자이다.

  • 생성자와 소멸자를 호출한다.

  • new[] / delete[]
    n 개의 데이터를 할당하려면 new [], delete[] 를 사용해야 한다.

BP* b3 = new BP[5];
delete[] b3;


오류

  • double free
  • heap overflow
  • use after free

반드시 할당한 메모리를 적절하게 해제하자.

함수나 연산자로 메모리를 할당할 때 커널에 요청해서 메모리를 받아온다.
(OS에서 제공하는 API를 사용)
CRT(C Runtime Library)의 힙 매니저는 malloc으로 할당된 메모리 내역을 관리하고 free의 요청을 받는다. 메모리 할당 내역을 저장

스코프를 벗어나도 사라지지 않는다.

일반 형식 객체는 스코프를 벗어나면 바로 소멸자가 호출되지만
동적할당을 한 객체는 Heap에 저장되기 때문에 delete를 해줘야 소멸자가 호출된다.

포인터에 관해

객체를 인자로 전달하거나 반환하면 생성자가 호출된다.
또 함수를 벗어나면 소멸자가 호출된다.
따라서 객체 포인터로 전달해 주는 것이 효율적이다.

Point p1[100]={}; 생성자 100개 호출
Point* p1[100]={}; 생성자 호출 안함

profile
rust로 뭐할까

0개의 댓글