포스트

[C++] 동적 메모리 할당

[C++] 동적 메모리 할당

C++ new/delete vs malloc/free 차이 정리

C++에서 동적 메모리를 할당하고 해제할 때는 new/deletemalloc/free를 사용할 수 있습니다. 하지만 이 둘은 작동 방식, 안전성, 객체 초기화 등 여러 면에서 중요한 차이가 있습니다.


1. 주요 차이 요약

항목new / deletemalloc / free
소속 언어C++C (C++에서도 사용 가능)
타입 정보 유지O (타입 추론됨)X (void* 반환)
생성자 / 소멸자 호출OX
오버로딩 가능 여부O (operator new)X
예외 처리실패 시 std::bad_alloc 예외실패 시 NULL 반환
캐스팅 필요 여부XO (명시적 캐스팅 필요)

2. new / delete 예제 (C++ 스타일)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass 생성자 호출\n"; }
    ~MyClass() { std::cout << "MyClass 소멸자 호출\n"; }
};

int main() {
    MyClass* obj = new MyClass();  // 생성자 호출됨
    delete obj;                    // 소멸자 호출됨

    int* arr = new int[5];         // int형 배열 할당
    delete[] arr;                  // 배열 해제 (주의: delete[] 사용)

    return 0;
}

결과:

1
2
MyClass 생성자 호출
MyClass 소멸자 호출

3. malloc / free 예제 (C 스타일)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <cstdlib> // malloc, free
#include <cstring> // memset

class MyClass {
public:
    MyClass() { std::cout << "MyClass 생성자 호출\n"; }
    ~MyClass() { std::cout << "MyClass 소멸자 호출\n"; }
};

int main() {
    // 메모리만 할당됨, 생성자 호출되지 않음
    MyClass* obj = (MyClass*)malloc(sizeof(MyClass));
    memset(obj, 0, sizeof(MyClass)); // 위험: vtable 등 초기화 파괴 가능

    // 직접 생성자 호출도 가능하지만 매우 비추천
    // new(obj) MyClass();  // placement new

    free(obj); // 소멸자 호출되지 않음 → 리소스 누수 가능성

    int* arr = (int*)malloc(sizeof(int) * 5); // 배열 할당
    free(arr);

    return 0;
}

결과:

  • 출력 없음 (생성자/소멸자 호출되지 않음)

4. 혼용 금지 예제

1
2
3
4
5
int* p1 = (int*)malloc(sizeof(int));
// delete p1; // 잘못된 해제 → undefined behavior

int* p2 = new int;
// free(p2);  // 잘못된 해제 → undefined behavior

반드시 newdelete로, mallocfree로 해제해야 합니다.


5. 언제 어떤 걸 써야 하나?

상황권장 방법
일반적인 객체 생성/삭제new / delete 사용
생성자/소멸자 포함된 클래스new / delete 필수
C API와 연동할 때malloc / free 가능
고성능/커스텀 메모리 제어상황에 따라 선택 (Placement new 등)

6. 결론

  • C++에서는 new/delete 사용이 기본입니다.
  • malloc/free는 객체의 생성자/소멸자를 무시하기 때문에 클래스 타입에는 위험합니다.
  • 둘을 혼용하면 undefined behavior가 발생하므로 매칭을 정확히 지켜야 합니다.

C++의 객체 지향 기능을 안전하게 활용하려면 new/delete를 사용하고, 필요 시 스마트 포인터(std::unique_ptr, std::shared_ptr)를 활용하는 것이 바람직합니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.