new 연산자로 동적 할당을 하면 리턴 값을 포인터로 받아서 사용해야 한다.
아래 두 영역의 코드는 할당 방식이 다르지만 매우 흡사한 코드이다.
{
// 정적 할당
int Value = 0;
int* Ptr = &Value;
}
{
// 동적 할당
int* Ptr = new int(0);
}
어떤 메모리를 원할 때 원하는 만큼 생성할 수 있다. C스타일 동적할당(malloc, remalloc, free)은 추후에 번외(?)로 배울 예정이다.
배열을 동적으로 할당할 수 있다는 것의 의미가 크다. If문 등과 연계하면 많은 것이 가능해진다.
new int(10); // X, 리턴 값을 받지 않음
reinterpret_cast<int*>(operator new(sizeof(int))); // new int()의 본모습
아래 예시에서 먼저 할당됐던 500번지(예시)의 int 메모리는 leak이 되어버렸다.
int* Ptr = new int(); // 500번지에 메모리 생김, Ptr은 500번지 가리킴
Ptr = new int(); // 600번지에 메모리 생김, Ptr은 600번지 가리킴
delete Ptr; // 600번지만 delete됨
nullptr은 사용할 수 없다.
nullptr 체크는 무조건 해야 한다.
int* Ptr = nullptr;
//*Ptr = 200; <- null 레퍼런스 익셉션 발생함
if (nullptr != Ptr) {
*Ptr = 200;
}
동적 할당을 하면 힙영역의 주소가 나온다.
delete를 하고 나서 포인터가 nullptr이 되는 것이 아니다. (delete 후 어디를 가리키게 되는지는 컴파일러에 따라 다를 수도 있고 어찌되는지 모르는 일이다.)
그래서 이런 코드가 안 먹힘.
아래 코드에서 *Ptr = 20;
← 이걸 댕글링포인터라고 한다. 쓰기 엑세스 위반 예외가 발생한다.
nullptr을 delete하는 것은 좋은 코드가 아니다. (delete 내부에서 방어해주긴 함)
0번지를 해제하는 것은 말이 안 됨.
int* Ptr = nullptr;
if (nullptr != Ptr) {
delete Ptr;
Ptr = nullptr;
}
새 프로젝트 만든다.
ConsoleScreen을 만들어볼거다. 기본 필터는 전부 삭제함. (취향)
만들고 싶은 게임 프로젝트 만든다.
ex) Galaga 갤러그 프로젝트
Galaga 프로젝트에서 ConsoleEngine의 클래스를 사용하고 싶다.( = ConsoleEngine 라이브러리를 사용하고 싶다.) → 다른 프로젝트니까 지금은 당연히 안 됨.
Galaga 프로젝트의 속성 > 구성 > "모든 구성" 선택
Galaga 프로젝트의 속성 > 플랫폼 > "모든 플랫폼" 선택
포함 디렉터리 > "..\;" 추가
라이브러리 프로젝트인 ConsoleEngine에 테스트용으로 함수를 만들고 그걸 컨텐츠 프로젝트인 Galaga에서 사용하는 것이 핵심.
ConsoleScreen의 헤더만 사용이 가능해졌을뿐 cpp파일을 사용하는 설정은 하지 않았기 때문에 아직 구현된 내용은 사용하지 못하고 있다.
컨텐츠 프로젝트인 Galaga에서 참조 추가 > ConsoleEngine 체크
그래도 안 된다. 최초에 빈프로젝트로 만들었기 때문에 exe로 되어있는데 그 설정을 바꿔야 한다.
라이브러리 프로젝트의 속성 > 구성 속성 > 일반 > 구성 형식 > "정적 라이브러리" 선택
여기까지 하면 된다.
수동으로 프로젝트 종속성을 넣어줘야 할 수도 있다.
솔루션 속성 > 프로젝트 종속성 > 컨텐츠 프로젝트 선택 > 라이브러리 프로젝트 체크