C++ new 연산자와 delete 연산자

프로그래밍/C++ 2019.10.17 댓글 Plorence

new, delete연산자는 동적 할당과 해제에 연관되어 있으며 C++에서 제공하는 방법입니다.

C언어에서는 malloc함수와 free함수를 통해서 동적 할당과 해제가 가능했었습니다.

 

동적 할당의 필요성

동적 할당은 미리 할당할 필요도 없으며, 원하는 크기를 정확히 할당이 가능하므로 쓸모없는 크기를 잡아먹지 않게 됩니다.

만약 계속 문자열을 입력받고 계산해야하는데 입력받은 문자열의 크기는 10~10000이라고 가정합시다.

동적 할당을 하지 않을 경우 정적 할당(지역변수)으로 최대 문자열의 크기인 10000을 잡고 미리 할당해야 합니다.(이런 경우 입력 문자열이 10이라면 필요 없는 메모리 공간이 9990이나 됩니다.)

하지만 동적할당은 입력받은 문자열의 크기를 구해서, 그 크기만큼 동적 할당하게 되면 필요 없는 메모리 공간이 생기지 않게 됩니다.

 

new 연산자

TypeName * ptr = new TypeName;

new 연산자는 C언어에서 malloc함수의 역할과 같습니다.

malloc함수도 필요한 만큼의 메모리 공간을 할당하고,new 연산자도 마찬가지입니다.

 

new 연산자 뒷부분에는 데이터형이 오는데 현재 표준 데이터형인 int가 와있습니다.

이게 '데이터형'이기만 하면 상관없습니다. 데이터형이면 가능합니다.

즉 사용자 정의 데이터형이어도 됩니다.

new 연산자는 데이터형의 크기를 파악한 후에 그 크기만큼 메모리 공간에 할당하게 됩니다.

그리고 그 주소를 리턴합니다.(할당한 메모리 공간의 주소)

그래서 포인터 변수사용하는 이유입니다.

 

동적할당과 동시에 초기화 하기

include <iostream>
class A {
public:
       A(int a, int b) {
              int c = a * b;
       }
};
struct B {
       int a;
       int b;
};
int main(void) {
       int * ptr1 = new int(123);
       A * ptr2 = new A(1, 2);
       B * ptr3 = new B({ 1,2 });
       std::cout << ptr3->a << " " << ptr3->b;
}

동적 할당할 때 동시에 초기화도 가능한데, 타입에 상관없이 가능합니다.

하지만 구조체는 대괄호로 씌워줘야 가능합니다.

만약 ()만 써준다면 초기값은 0이 됩니다.

 

동적 배열

TypeName * ptr = new TypeName[Length];

new 연산자로 동적 배열도 가능합니다.

Length부분에 길이를 넣으면 그 길이만큼의 배열이 동적 할당됩니다.

사용법은 정적 배열을 다룰 때랑 똑같습니다.

동적 배열도 ()사용 시 0으로 채워줍니다.

int * ptr = new int[10]();

 

new 연산자 사용시 주의할 점

new 연산자가 꼭 할당된 메모리 공간의 주소를 리턴하지 않습니다.

왜냐하면 메모리 부족으로 인해 정상적인 할당이 불가능할 때가 있기 때문입니다.

이런 경우에는 new 연산자가 0을 리턴합니다. C++에서 '값'이 0인 포인터를 널 포인터(Null pointer)라고 부릅니다.

널 포인터는 아무것도 지시하지 않는다는 의미입니다.

 

delete 연산자

delete 연산자는 new 연산자의 반대되는 의미로서 new 연산자로 할당한 메모리 공간을 해제해주는 역할을 합니다.

delete ptr;

이때 ptr은 동적 할당한 메모리 공간을 지시하고 있는 포인터여야 합니다.

 

동적 배열에서의 delete

동적배열에서의 delete는 동적 할당된 일반적인 변수와는 방법이 흡사하지만 다릅니다.

delete[] ptr;

동적 배열을 할당 해제한다는 걸 알리기 위해 delete에서 추가로 []를 써주시면 됩니다.

 

new, delete 연산자를 사용할 때 주의해야 할 것

  • new연산자로 대입하지 않은 메모리는 delete연산자로 해제하지 않습니다.

  • 할당된 메모리 공간을 두 번 이상 delete연산자로 해제하지 않습니다.

  • new []로 할당된 메모리 공간은 반드시 delete [] 연산자로 할당 해제를 합니다.

  • 널 포인터 일시 delete연산자를 사용해도 아무런 문제가 없습니다.

 

댓글