소멸자로부터 예외가 터져 나가는 경우를 C++ 언어에서 막는 것은 아니지만, 실제 상황을 들춰보면 확실히 우리가 막을 수밖에 없는 것 같습니다. 예를 들어 보죠. class Widget{ public: ~ Widget(){ } //이 함수로부터 예외가 발생합니다. }; void doSometing() { std::vector v; ... }// v는 여기서 자동으로 소멸됩니다. 다음과 같은 상황에서 백터 v가 10개라고 가정하였을 때, 함수가 끝나고 소멸하게 되는데 이때 첫 번째 객체에서 소멸자가에서 오류가 발생한 이후, 또 다시 두 번째 객체에서 소멸자에서 오류가 발생하게 되면, 두개의 예외가 동시에 만들어진 상태입니다. 그렇게 되면 프로그램이 터지던지 정의되지 않은 행동을 보일텐데 이때는 정의되지 않..
Class를 생성할 때, 컴파일러는 기본적으로 생성자, 소멸자, 복사 생성자, 복사 대입 생성자를 자동으로 생성하게 된다. class Empty(){ public: Empty(){ } ~Empty() { } Empty(const Empty& rhs) { } Empty& operator=(const Empty& rhs) { } } Empty e1;// 기본 Empty e2(e1);// 복사 e2 = e1;// 복사 대입 이렇게 자동으로 생성되는 코드는 예상치 못한 오류를 일으킬 수 있습니다. 예를 들어 가상 소멸자가 생성되어야 하는데 비가상 소멸자가 생성된다던가, 몰래 만들어진 복사 생성자로 인해 객체가 예상치 못한 작동을 할 수도 있죠. 고로 이러한 함수들은 막거나, 직접 생성하여야 합니다. 이 내용은 ..
Effective C++을 읽는 도중에, 이 내용은 꼭 필요한거 같아서 이렇게 기록합니다. 새로 정의한 타입의 객체 생성 및 소멸은 어떻게 이루어져야 하는가? 더보기 설계에 따라서 클래스 생성자 및 소멸자의 설계가 바뀌게 됩니다. 뿐만 아니라 메모리 할당 함수(operator new, new[], delete, delete[])를 직접 작성할 경ㅇ에는 이들 함수의 설계에도 영향을 미칩니다. 객체 초기화는 객체 대입과 어떻게 달려져야 하는가? 더보기 초기화와 대입을 다르게 두는 것이 중요한데, 각각에 해당하는 함수 호출이 다르기 때문입니다. 새로운 타입으로 만든 객체가 값에 의해 전달되는 경우에 어떤 의미를 줄 것인가? 더보기 어떤 타입에 대해 '값에 의한 전달'을 구현하는 것은 복사 생성자이기 때문에, ..
: 메모리 풀이란, 동적할당한 메모리들을 만들어 Pool에 저장한 후, 필요할 때 Pool에서 꺼내 사용하고 반납하는 형식을 말한다. 이런 방식을 사용하는 이유는 동적할당 함수, 즉 malloc이나 new을 호출하는 시간을 줄여, 속도 향상을 꾀하기 위해 사용합니다. 메모리 풀의 형태를 두 가지정도 배웠는데, 여기는 첫 번째 형태를 적어보겠습니다. 메모리 풀의 형태 [Header][Data]가 하나의 형태를 가집니다. 메모리 헤더를 다는 이유는 Data의 크기를 알아내기 위해 사용합니다. 그래서 Pool의 형태는 [Header][Data][Header][Data][Header][Data] 식으로, Header를 꺼내 사용하는 형식으로 되어있습니다. 메모리 Pool - Header struct Memory..
C++에서 우리가 자주 쓰는 vector, map, queue 등, STL 자료구조는 원래 지정하지 않아도 자동으로 동적할당과 해제까지 다 해주는 아주 편리한 함수입니다. 여기서 이 자동으로 동적할당과 해제를 해주는 Allocator를 본인이 직접 작성하여 넣어줄 수도 있습니다. vector를 호출할 때 인자를 살펴보게 되면 다음과 같이 두개의 인자를 받을 수 있는데, 첫번째는 클래스, 두 번째가 바로 Allocator 입니다. template class vector { // varying size array of values 이 allocator는 필수로 하는 함수가 두가지 있는데 그것은 allocate 와 deallocate 입니다. 다음은 강의의 예시입니다. 다음과 같이 allocate와 deall..
오늘은 virtualAllloc과 virtualFree 함수를 공부하였습니다. 자세한 내용은 아래는 Microsoft 공식문서에 있는 두 함수의 원형입니다. 아래 더보기는 각 함수에 대한 설명입니다. LPVOID VirtualAlloc( [in, optional] LPVOID lpAddress, [in] SIZE_T dwSize, [in] DWORD flAllocationType, [in] DWORD flProtect ); 더보기 첫 번째 인자 - 먼저 공통적으로 첫 번째 인자는, 시작할 주소 또는 해제할 주소의 시작지점을 인자로 받습니다. 시작 지점이 없이 랜덤한 공간을 할당받을 경우 NULL을 입력하면 됩니다. 두 번째 인자 - 두 번째로, 할당할 사이즈의 크기입니다. 세 번째 인자 - Alloc할때..
placement 문법이란, 내가 malloc등으로 생성한 동적 memory를 type 캐스팅을 통해 클래스로 변환하였을 경우, 생성자 호출이 되지 않는데 이러한 상황에서 생성자를 호출하는 방법이다. 정리 void* ptr = malloc(size) -> ptr을 static_cast 등을 통해 형변환 후 new(ptr)클래스이름(인자) 로 생성자 호출(초기화) 고로 내가 원하는 데이터 영역을 할당하여 사용할 수 있게 된다. (굳이 malloc 말고, 이미 만들어진 데이터 공간도 크기만 맞다면 가능) ※ std::forward 같은 경우에는 args로 들어온 값을 인자로써 들어갈 수 있도록 해주는 함수입니다. template T* xnew(types... args) { // placement new vo..
게임 서버 공부를 다시 시작하면서, 먼저 메모리 구조와 포인터를 조금 이해해보고자 하였습니다. 그래서 제일 먼저 shaerd_ptr을 구현을 하려고 합니다. 참고는 memory에 있는 shared_ptr의 구조를 살짝 참조하여 만들었고, 추가적인 형태는 따로 다시 만들어볼 예정입니다. 아래는 코드입니다. 먼저 template를 사용해서 원하는 형태로 생성 할 수 있도록 하였습니다. 추가적으로 활용할만한 operator 함수들을 넣을 예정입니다. template class Shared_Ptr { public: Shared_Ptr(const Ref_Count* ref); ~Shared_Ptr() { Release(); } // 복사 생성자 Shared_Ptr(const Shared_Ptr& tmp) noex..