반응형

1. 동적 할당

동적 할당이란, 프로그래머가 원하는 만큼의 공간을 프로그램 실행시간 중에 할당하여 사용하는 것이다.

할당된 공간은 프로그램 종료까지 남아있으므로, 프로그래머가 사용이 끝나면 적절히 해제시켜주어야 한다.

C++에서 동적 할당은 다음과 같이 이루어진다.

#include<iostream>

int main()
{
	int* iNumber = new int;
	std::cin >> *iNumber;
	std::cout << "Number :" << *iNumber << std::endl;
	delete iNumber;
	return 0;
}

그림 1. 실행결과.

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;
}

그림 2. 실행결과.

배열의 경우에는 []로 할당받을 공간의 크기를 추가적으로 알려주어서 공간을 할당받고,

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;
}

그림 3. 실행결과.

소멸자는 객체가 소멸할 때 호출된다.

클래스 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;
}

그림 4. 실행결과.

소스를 보면, 생성자에서 동적 할당을 사용해서 공간을 할당하고,

소멸자에서 그 공간을 해제하고 있다.


읽을거리.

동적 할당 시 주의점

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만 사용하면

나머지 뒤에 연속된 공간을 해제하지 않아서 메모리 누수가 발생한다.

그림 5. 에러.

 

반응형

'개념정리 > 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

+ Recent posts