2 분 소요

개요

  • 런타임 시점에 프로세스의 힙 영역에 메모리 공간을 할당
  • 명시적 해제 필요
  • malloc/calloc과 free, new와 delete가 쌍을 이뤄 사용
  • malloc
    • 메모리 할당 후 쓰레기값으로 초기화
    • 생성자를 호출하지 않음
  • calloc
    • 메모리 할당 후 0으로 초기화
    • 생성자를 호출하지 않음
  • free
    • 소멸자를 호출하지 않고 메모리 해제
  • new
    • operator new로 메모리 할당 후 생성자를 호출
  • delete
    • 소멸자 호출 후 operator delete로 메모리 해제
  • operator new
    • malloc/calloc과 같이 생성자 호출 없이 메모리만 할당
    • 오버로딩 가능
    • new 대신 사용하여 조금 더 정교한 메모리 관리 가능
    • placement new로 객체를 초기화하여 사용
  • operator delete
    • free와 같이 소멸자 호출 없이 메모리만 해제
    • delete 대신 사용하여 조금 더 정교한 메모리 관리 가능


예제

  • 코드
    #include <cstdlib>
    #include <iostream>

    using namespace std;

    class Test {
    	private:
    		int i;

    	public:
    		Test(int i) : i(i) {}
    		~Test() = default;

    		void Print() { cout << this->i << endl; }
    };

    void *operator new(size_t size, int i) {
    	cout << __PRETTY_FUNCTION__ << endl;
    	return malloc(size);
    }

    void operator delete(void *ptr, int i) {
    	cout << __PRETTY_FUNCTION__ << endl;
    	return free(ptr);
    }

    void malloc_test() {
    	cout << "--- " << __func__ << " start ---" << endl;

    	int *i = NULL;

    	i = static_cast<int *>(malloc(sizeof(int) * 1));
    	*i = 1;
    	cout << *i << endl;
    	free(i);

    	i = static_cast<int *>(malloc(sizeof(int) * 2));
    	i[0] = 0;
    	i[1] = 1;
    	cout << i[0] << ", " << i[1] << endl;
    	free(i);

    	Test *t = static_cast<Test *>(malloc(sizeof(Test) * 1));
    	new (t) Test(1);
    	t->Print();
    	free(t);

    	cout << "--- " << __func__ << " end ---" << endl;
    }

    void calloc_test() {
    	cout << "--- " << __func__ << " start ---" << endl;

    	int *i = NULL;

    	i = static_cast<int *>(calloc(1, sizeof(int)));
    	*i = 1;
    	cout << *i << endl;
    	free(i);

    	i = static_cast<int *>(calloc(2, sizeof(int)));
    	i[0] = 0;
    	i[1] = 1;
    	cout << i[0] << ", " << i[1] << endl;
    	free(i);

    	Test *t = static_cast<Test *>(calloc(1, sizeof(Test)));
    	new (t) Test(1);
    	t->Print();
    	free(t);

    	cout << "--- " << __func__ << " end ---" << endl;
    }

    void new_test() {
    	cout << "--- " << __func__ << " start ---" << endl;

    	int *i = NULL;

    	i = new int;
    	*i = 1;
    	cout << *i << endl;
    	delete i;

    	i = new int[2];
    	i[0] = 0;
    	i[1] = 1;
    	cout << i[0] << ", " << i[1] << endl;
    	delete[] i;

    	Test *t = new Test(1);
    	t->Print();
    	delete t;

    	cout << "--- " << __func__ << " end ---" << endl;
    }

    void operator_new_test() {
    	cout << "--- " << __func__ << " start ---" << endl;

    	Test *t = NULL;

    	t = static_cast<Test *>(operator new(sizeof(Test)));
    	t = new (t) Test(1);
    	t->Print();
    	t->~Test();
    	operator delete(t);

    	cout << "~~~" << endl;

    	t = new (1) Test(2);
    	t->Print();
    	operator delete(t, 1);

    	cout << "--- " << __func__ << " end ---" << endl;
    }

    int main() {
    	malloc_test();
    	cout << endl << endl;
    	calloc_test();
    	cout << endl << endl;
    	new_test();
    	cout << endl << endl;
    	operator_new_test();

    	return 0;
    }
  • 실행 결과
    --- malloc_test start ---
    1
    0, 1
    1
    --- malloc_test end ---


    --- calloc_test start ---
    1
    0, 1
    1
    --- calloc_test end ---


    --- new_test start ---
    1
    0, 1
    1
    --- new_test end ---


    --- operator_new_test start ---
    1
    ~~~
    void* operator new(size_t, int)
    2
    void operator delete(void*, int)
    --- operator_new_test end ---