Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++의 delete 연산자와 free() 함수, 동적 메모리 해제 방법 총정리


delete 연산자란?

C++에서 delete 연산자는 new 연산자로 동적으로 할당한 메모리를 해제할 때 사용합니다. 개발자는 이 연산자를 통해 직접 생성한 포인터 변수가 가리키는 메모리를 명시적으로 반환할 수 있으며, 이를 통해 메모리 누수(memory leak)를 방지할 수 있습니다.

C++에서 delete 연산자의 기본 문법은 다음과 같습니다.

delete pointer_variable;

배열 형태로 할당된 메모리 블록 전체를 해제하려면 대괄호([])를 함께 사용합니다.

delete[ ] pointer_variable;

delete 연산자 예제

다음은 C++에서 delete 연산자를 사용하는 예제 코드입니다.

#include <iostream>
using namespace std;
int main () {
    int *ptr1 = NULL;
    ptr1 = new int;
    float *ptr2 = new float(299.121);
    int *ptr3 = new int[28];
    *ptr1 = 28;
    cout << "Value of pointer variable 1 : " << *ptr1 << endl;
    cout << "Value of pointer variable 2 : " << *ptr2 << endl;
    if (!ptr3)
    cout << "Allocation of memory failed\n";
    else {
        for (int i = 10; i < 15; i++)
        ptr3[i] = i+1;
        cout << "Value of store in block of memory: ";
        for (int i = 10; i < 15; i++)
        cout << ptr3[i] << " ";
    }
    delete ptr1;
    delete ptr2;
    delete[] ptr3;
    return 0;
}

실행 결과

Value of pointer variable 1 : 28
Value of pointer variable 2 : 299.121
Value of store in block of memory: 11 12 13 14 15

코드 설명

위 프로그램에서는 세 개의 포인터 변수 ptr1, ptr2, ptr3를 선언했습니다. ptr1과 ptr2는 new 연산자로 메모리를 할당받아 값을 초기화했고, ptr3는 new 연산자를 통해 정수 28개 크기의 배열 메모리 블록을 할당받아 저장하고 있습니다.

int *ptr1 = NULL;
ptr1 = new int;
float *ptr2 = new float(299.121);
int *ptr3 = new int[28];
*ptr1 = 28;

이후 배열의 요소에 값을 저장하고 출력한 뒤, 할당된 메모리를 해제하기 위해 단일 변수에는 delete, 배열에는 delete[]를 각각 사용합니다.

delete ptr1;
delete ptr2;
delete[] ptr3;

주의할 점은 new로 배열을 할당했다면 반드시 delete[]로 해제해야 한다는 것입니다. 일반 delete로 배열 메모리를 해제하면 정의되지 않은 동작(undefined behavior)이 발생할 수 있습니다.

free() 함수란?

C 언어의 free() 함수는 malloc(), calloc(), realloc() 등으로 동적 할당한 메모리를 해제하는 데 사용됩니다. free() 함수를 호출해도 포인터 변수 자체의 값은 변경되지 않으며, 포인터는 여전히 같은 메모리 위치를 가리킵니다(이를 댕글링 포인터(dangling pointer)라고 하므로, 해제 후에는 포인터에 NULL을 대입하는 것이 안전합니다).

C 언어에서 free() 함수의 문법은 다음과 같습니다.

void free(void *pointer_name);

여기서 각 매개변수의 의미는 다음과 같습니다.

pointer_name − 해제할 메모리를 가리키는 포인터의 이름입니다.

free() 함수 예제

다음은 C 언어에서 free() 함수를 사용하는 예제입니다.

#include <stdio.h>
#include <stdlib.h>
int main() {
    int n = 4, i, *p, s = 0;
    p = (int*) malloc(n * sizeof(int));
    if(p == NULL) {
        printf("\nError! memory not allocated.");
        exit(0);
    }
    printf("\nEnter elements of array : ");
    for(i = 0; i < n; ++i) {
        scanf("%d", p + i);
        s += *(p + i);
    }
    printf("\nSum : %d", s);
    free(p);
    return 0;
}

실행 결과

Enter elements of array : 32 23 21 28
Sum : 104

코드 설명

위 프로그램에서는 네 개의 변수를 선언했으며, 그중 포인터 변수 *p가 malloc()으로 동적 할당한 메모리의 주소를 저장합니다.

int n = 4, i, *p, s = 0;
p = (int*) malloc(n * sizeof(int));

사용자로부터 배열 요소를 입력받아 그 합계를 출력한 후, 다음 코드로 할당된 메모리를 해제합니다.

free(p);

delete와 free()의 차이점

두 기능 모두 동적 메모리를 해제하지만 몇 가지 중요한 차이가 있습니다.

1. 언어적 속성: delete는 C++의 연산자(operator)이며, free()는 C 표준 라이브러리의 함수(function)입니다.

2. 소멸자 호출 여부: delete는 객체를 해제하기 전에 해당 클래스의 소멸자(destructor)를 자동으로 호출하지만, free()는 소멸자를 호출하지 않습니다.

3. 사용 대상: new로 할당한 메모리는 반드시 delete로, malloc()으로 할당한 메모리는 반드시 free()로 해제해야 합니다. 서로를 혼용하면 미정의 동작이 발생할 수 있습니다.

4. 속도: free()는 함수 호출 오버헤드가 상대적으로 적어 일반적으로 delete보다 약간 빠른 편입니다.