메모리의 동적 할당
데이터 영역과 스택 영역에 할당되는 메모리의 크기는 컴파일 타임에 미리 결정이 됩니다.
하지만 힙 영역의 크기는 프로그램이 실행되는 도중인 런 타임에 사용자가 직접 결정하게 됩니다.
이렇게 런 타임동안 힙 영역에 메모리를 할당받는 것을 메모리의 동적 할당이라고 합니다.
포인터의 가장 큰 목적은 런 타임에 이름 없는 메모리를 할당받아 포인터에 할당하여, 할당받은 메모리에 접근하는 것입니다.
C언어에서도 malloc() 함수 등의 라이브러리 함수를 제공하여 이러한 작업을 수행할 수 있게 해줍니다.
하지만 C++에서는 메모리의 동적 할당 및 해제를 위한 더욱 효과적인 방법을 new 연산자와 delete 연산자를 통해 제공합니다.
new 연산자
C언어에서는 malloc() 함수 등을 이용하여 메모리의 동적 할당을 수행합니다.
C++에서도 위의 함수를 사용할 수 있지만, 더 나은 방법인 new 연산자를 이용한 방법을 제공하고 있습니다.
C++에서 new 연산자는 다음과 같은 문법으로 사용합니다.
타입* 포인터이름 = new 타입;
첫 번째 타입은 데이터에 맞는 포인터를 선언하기 위해, 두 번째 타입은 메모리의 종류를 지정하기 위해 사용됩니다.
만약 사용할 수 있는 메모리가 부족하여 새로운 메모리를 만들지 못했다면, new 연산자는 null 포인터를 반환합니다.
new 연산자는 자유 기억 공간이라고 불리는 메모리 공간에 객체를 위한 메모리를 할당받습니다.
또한, new 연산자를 통해 할당받은 메모리는 따로 이름이 없으므로 해당 포인터로만 접근할 수 있게 됩니다.
delete 연산자
C언어에서는 free() 함수를 이용하여 동적으로 할당받은 메모리를 다시 운영체제로 반환합니다.
이와 마찬가지로 C++에서는 delete 연산자를 사용하여, 더는 사용하지 않는 메모리를 다시 메모리 공간에 돌려줄 수 있습니다.
C++에서 delete 연산자는 다음과 같은 문법으로 사용합니다.
delete 포인터이름;
다음 예제는 런 타임에 int형과 double형 데이터를 위한 메모리를 할당받고, delete 연산자를 사용하여 더 이상 사용하지 않는 메모리를 반환하는 예제입니다.
int* ptr_int = new int;
*ptr_int = 100;
double* ptr_double = new double;
*ptr_double = 100.123;
cout << "int형 숫자의 값은 " << *ptr_int << "입니다." << endl;
cout << "int형 숫자의 메모리 주소는 " << ptr_int << "입니다." << endl;
cout << "double형 숫자의 값은 " << *ptr_double << "입니다." << endl;
cout << "double형 숫자의 메모리 주소는 " << ptr_double << "입니다." << endl;
delete ptr_int;
delete ptr_double;
int형 숫자의 값은 100입니다.
int형 숫자의 메모리 주소는 0x1d83010입니다.
double형 숫자의 값은 100.123입니다.
double형 숫자의 메모리 주소는 0x1d83030입니다.
이때 new 연산자를 통해 생성한 메모리가 아닌 변수를 선언하여 생성한 메모리는 delete 연산자로 해제할 수 없습니다.
delete 연산자는 반드시 new 연산자를 통해 할당된 메모리를 해제할 때에만 사용해야 합니다.
또한, 한 번 해제한 메모리를 다시 해제하려고 시도하면 오류가 발생합니다.
그리고 이렇게 힙에 할당된 변수는 다음 예제와 같이 참조자의 선언을 통해서도 포인터 연산 없이 힙 영역에 접근할 수도 있습니다.
예제
int *ptr = new int;
int &ref = *ptr;
ref = 20;
cout <<*ptr<<endl;
실행 결과
20
참고
<열혈 c++ 프로그래밍 p93~p95>
'C++' 카테고리의 다른 글
(C++) 범위 기반 for문과 auto 키워드 (0) | 2022.11.07 |
---|---|
(C++) Visual Studio #include <bits/stdc++.h> (0) | 2022.10.07 |
(C++) 클래스의 상속 (부모 클래스, 자식 클래스) (0) | 2022.09.03 |
(C++) 정적 멤버와 상수 멤버(static, const) (0) | 2022.09.03 |
(C++) 생성자와 소멸자(디폴트 생성자, 복사 생성자) (2) | 2022.08.20 |