1. 동적 할당
동적 할당이란, 프로그래머가 원하는 만큼의 공간을 프로그램 실행시간 중에 할당하여 사용하는 것이다.
할당된 공간은 프로그램 종료까지 남아있으므로, 프로그래머가 사용이 끝나면 적절히 해제시켜주어야 한다.
C++에서 동적 할당은 다음과 같이 이루어진다.
#include<iostream>
int main()
{
int* iNumber = new int;
std::cin >> *iNumber;
std::cout << "Number :" << *iNumber << std::endl;
delete iNumber;
return 0;
}
new라는 키워드를 사용해 공간을 할당하고,
delete라는 키워드를 사용해서 공간을 해제하고 있다.
배열의 경우에는 어떻게 할까?
#include<iostream>
int main()
{
int* iArray = new int[5];
for (int i = 0; i < 5; i++)
std::cin >> iArray[i];
std::cout << "iArray :";
for (int i = 0; i < 5; i++)
std::cout << iArray[i] << " ";
std::cout << std::endl;
delete[] iArray;
return 0;
}
배열의 경우에는 []로 할당받을 공간의 크기를 추가적으로 알려주어서 공간을 할당받고,
delete []로 연속된 공간을 해제시키고 있다.
2. 소멸자
생성자는 클래스 초기화를 위해 만들어졌다면, 소멸자는 청소를 위해 만들어졌다.
소멸자는 반환형과 매개변수가 없고, 클래스 이름 앞에 ~를 붙여 나타낸다.
#include<iostream>
class iClass
{
std::string name;
public:
iClass(std::string name)
{
this->name = name;
std::cout << name << "생성자 호출!" << std::endl;
}
~iClass()
{
std::cout << name << "소멸자 호출!" << std::endl;
}
};
int main()
{
iClass c("클래스1");
iClass* cp = new iClass("클래스2");
delete cp;
return 0;
}
소멸자는 객체가 소멸할 때 호출된다.
클래스 2는 동적 할당으로 생성하여 delete로 명시적으로 해제하였으므로,
먼저 소멸자가 호출된 것을 볼 수 있다.
사실 위와 같은 예제에서는 소멸자가 필요가 없다.
객체 내부에서 동적 할당을 사용했다면, 그 공간을 해제시켜 주어야 한다.
그럼 언제 해제시키는 것이 가장 이상적일까?
객체가 더 이상 사용될 일이 없는 소멸 단계에서 해제되는 것이 가장 이상적일 것이다.
따라서 소멸자는 객체 내부에서 사용된 메모리를 정리할 때 사용하는 게 좋다.
#include<iostream>
class IArray
{
int* arr;
int size;
public:
IArray(int size)
{
this->size = size;
arr = new int[size];
}
~IArray()
{
delete[] arr;
}
void InitArray()
{
std::cout << "Input(" << size << ") : ";
for (int i = 0; i < size; i++)
std::cin >> arr[i];
}
void ShowArray()
{
std::cout << "Array(" << size << ") : ";
for (int i = 0; i < size; i++)
std::cout << arr[i] << " ";
std::cout << std::endl;
}
};
int main()
{
IArray arr = IArray(5);
arr.InitArray();
arr.ShowArray();
return 0;
}
소스를 보면, 생성자에서 동적 할당을 사용해서 공간을 할당하고,
소멸자에서 그 공간을 해제하고 있다.
읽을거리.
동적 할당 시 주의점
new []를 사용했다면 delete [],
new를 사용했다면 delete를 써야 한다는 것을 명심하자.
#include <iostream>
class A
{
public:
A()
{
std::cout << "생성자 호출!" << std::endl;
}
~A()
{
std::cout << "소멸자 호출!" << std::endl;
}
};
int main()
{
A* ptr = new A[10];
delete ptr; // 에러!
return 0;
}
new []를 사용하여 배열로 공간을 할당했는데, delete만 사용하면
나머지 뒤에 연속된 공간을 해제하지 않아서 메모리 누수가 발생한다.
'개념정리 > C++' 카테고리의 다른 글
6. Friend 키워드 (0) | 2021.04.21 |
---|---|
5. 참조자 (0) | 2021.04.20 |
3. 클래스 (0) | 2021.04.18 |
2. Namespace (0) | 2021.04.17 |
1. 기본 자료형 및 입출력 (0) | 2021.04.15 |