동적인 메모리 할당
전역 변수는 프로그램의 실행 시작 시에 메모리가 할당된다. 또한 통상의 지역 변수는 함수 내 변수가 선언되었을 때에 메모리가 할당된다.
이들 방법 외에도 코드를 작성하는 사람이 지정하는 타이밍으로 메모리를 할당하는 방법이 있다. 이것을 동적인 메모리 할당(dynamic allocation)이라고 한다.
동적인 메모리를 할당하려면 new라는 연산자를 사용한다.
[구문 : new 연산자에 의한 메모리의 할당]
포인터 = new 형명;
동적으로 메모리를 할당하는 코드를 살펴보도록 한다.
int *pA;
pA = new int;
동적으로 메모리를 할당하려면 우선, 할당하는 형으로의 포인터(여기서는 pA)를 준비해 두어야 한다.
new 연산자는 메모리를 할당하고, 그 할당한 메모리의 주소를 반환한다. 그래서 이 주소를 포인터 pA에 저장하는 것이다. 또한 동적으로 메모리를 할당한 경우는 변수를 이용한 경우와 달리, 이 주소를 사용해서 메모리를 직접 취급해야 한다. 즉, 할당한 메모리에 무엇인가 값을 기억시킬 때는 그 포인터를 사용해서 다음과 같이 대입한다.
*pA = 50;
동적인 메모리의 해제
동적으로 메모리를 할당한 경우에 주의해야 할 것은 메모리가 필요 없으면, 코드를 작성하는 사람이 메모리를 해제하는 처리를 기술해야 한다. 지역 변수와 전역 변수와 달리, 메모리를 언제 해제할 것인가를 결정하지 않으면 안 된다.
동적으로 할당한 메모리를 해제하려면 다음과 같이 수행한다.
[구문 : delete 연산자에 의한 메모리의 해제]
delete 포인터 명
즉, 메모리를 이용하고 종료했다면 코드 내에
delete pA; //메모리를 해제한다.
로 기술해야 한다. 또한 이미 해제한 메모리에 대해 delete 연산자를 사용할 수는 없다.
변수를 이용한 경우와 비교해서 살펴보기로 한다.
예제) 동적인 메모리 할당
메모리를 동적으로 할당하는 경우의 일련의 순서를 작성해 보도록 한다.
#include <iostream>
using namespace std;
int main()
{
int* pA;
pA = new int;
cout << "동적으로 메모리를 할당하였습니다.\n";
*pA = 15;
cout << "동적으로 할당하는 메모리를 사용해서 " << *pA << "를 출력합니다.\n";
delete pA;
cout << "할당한 메모리를 해제하였습니다.\n";
return 0;
}
사실 작은 코드에서는 동적인 메모리의 할당의 편리성은 이해하기 어려울지 모른다. 그러나 많은 함수가 등장하는 대규모적인 코드인 경우를 생각해 보도록 한다. 함수의 시작, 종료에 상관없이 기억해 두고 싶은 값이 있는 경우에는 지역 변수는 사용하지 않는다. 지역 변수의 수명은 그 함수 내에서만 한정되어 있기 때문이다. 그러나 전역 변수에서는 프로그램의 실행 중에는 처음부터 끝까지 값을 유지할 수 있다. 이 2개의 방법에 비해, 동적으로 메모리를 할당하는 방법에서는 메모리를 필요로 할 때에 충분하게 이용할 수 있다.
배열을 동적으로 할당
배열을 취급할 때 동적으로 메모리를 할당하면 프로그램의 실행 시에 배열의 크기를 지정해서 취급할 수 있다. 배열 파트에서 설명한 것 같이 배열의 요소 수를 몇 개 이용할 것인가 알지 못하는 경우에는 배열의 요소를 크게 할당해 두어야 한다. 그러나 배열을 동적으로 할당하면 큰 배열을 준비할 필요는 없다. 배열의 크기 코드를 실행할 때 결정할 수 있다.
배열의 동적인 할당을 수행하는 구문은 다음과 같다.
[구문 : 동적인 배열의 할당]
포인터명 = new 형명[요소 수];
이 경우에도 배열을 이용하고 종료했다면 메모리를 해제해야 한다. 이것을 위해서는 다음과 같이 [ ]를 붙여 해제한다.
[구문 : 동적인 배열의 해제]
delete[] 포인터명;
그러면 실제로 배열을 동적으로 할당해 보는 것으로 한다.
예제) 동적 배열
배열을 동적 메모리로 생성하여 키보드로부터 점수를 입력받아 배열에 저장하고 점수를 출력한 후, 동적 메모리 배열을 해제하는 코드를 작성해 보도록 한다.
#include <iostream>
using namespace std;
int main()
{
int num;
int* pT;
cout << "몇 명의 시험 점수를 입력합니까? ";
cin >> num;
pT = new int[num];
cout << "인원수만큼 점수를 입력하세요.\n";
for (int i = 0; i < num; i++) {
cin >> pT[i];
}
for (int j = 0; j < num; j++) {
cout << j + 1 << "번째의 사람의 점수는 " << pT[j] << "입니다.\n";
}
delete[] pT;
return 0;
}
이와 같이 입력된 인원수만큼의 배열을 동적으로 할당하면 큰 배열을 준비할 필요가 없고 여분의 메모리를 사용하지 않고 해결되는 것이다.
파일의 분할
큰 코드를 작성할 때에는 많은 함수를 사용하게 된다. 일단 작성한 편리한 함수는 여러 가지 프로그램에서 재이용할 수 있으면 편리하다. 그렇게 하면 지금까지 작성한 함수를 사용해서 큰 코드를 곧바로 개발하기에 쉽기 때문이다.
이때 여러 번 다른 프로그램에서 이용하도록 하는 함수는 main() 함수와 같이 파일 내에 기술하는 것이 아니고, 다른 파일에 분할해서 기술하는 것이 보통이다. 파일을 분할함으로써 여러 가지 프로그램에서 이용하기 쉽게 하는 것이다.
예제) 함수를 여러 번 호출
사용자 정의 함수를 myfunc.h, myfunc.cpp 파일에 선언과 정의하고, main() 함수에서 사용자 정의 함수를 호출하는 코드를 작성해 보도록 한다.
//myfunc.h
int max(int x, int y);
//이 코드에서는 파일을 다음의 3개로 분할한다.
//myfunc.h 파일은 함수 프로토타입을 선언한다.
//myfunc.cpp
int max(int x, int y)
{
if (x > y)
return x;
else
return y;
}
//myfunc.cpp 파일은 myfunc.h 파일에서 선언한 max() 함수를 정의한다.
//ex10-5.cpp
#include <iostream>
#include "myfunc.h"
using namespace std;
//ex10-5.cpp 파일은 main() 함수(프로그램 본체)를 정의한다.
int main()
{
int num1, num2, ans;
cout << "1번째의 정수를 입력하세요=> ";
cin >> num1;
cout << "2번째의 정수를 입력하세요=> ";
cin >> num2;
ans = max(num1, num2);
cout << "최댓값은 " << ans << "입니다.\n";
return 0;
}
이 경우, 우선 예제 ex10-5.cpp, myfunc.cpp를 별개로 컴파일하여 객체 파일을 작성한다. 더욱이 이 객체 파일끼리를 링크함으로써 1개의 코드를 작성한다.
myfunc.h라는 파일에는 함수의 사양을 나타내는 함수 프로토타입 선언만을 기술해 둔다. 이와 같이 함수 프로토타입 선언을 종합한 파일을 헤더 파일(header file)이라고 한다.
함수를 이용하는 예제 ex10-5.cpp의 선두에는 헤더 파일인 myfunc.h를 읽어 들이도록 지정해 둔다. 이렇게 해 두면 파일을 분할해도 함수 프로토타입 선언에 의해 컴파일할 때 함수의 호출이 올바른가를 체크할 수 있다.
여러 개의 파일의 컴파일 및 링크의 순서는 사용하는 C++ 개발 환경에 따라 다르기 때문에 관련 설명서를 참고하도록 한다.
표준 라이브러리
C++의 개발 환경에는 어떤 프로그램에서 사용되는 표준적인 처리에 관해 이미 정의된 함수가 첨부되어 있다. 이것을 표준 라이브러리(standard library)라고 한다. 지금까지 사용해온 입출력 기능과 문자열 조작 함수도 표준 라이브러리의 함수이다.
이 함수를 이용하려면 표준 헤더 파일을 인크루드 하는 것으로 되어 있다.
표준 헤더 파일을 인크루드 하려면 < >로 둘러싼다. 한편, 자기 자신이 작성한 헤더 파일을 인크루드 하려면 " "로 둘러싼다.
#include <iostream>
#include "myfunc.h"
통상 < >로 둘러싼 파일은 표준 라이브러리로 개발 환경이 지정되어 있는 디렉터리(폴더)에서 읽힌다. 한편, " "로 둘러싼 헤더 파일은 자기 자신이 작성한 소스 파일인 디렉터리에서 읽히도록 되어 있다.
출처: 박흥복, 서정희. 2015. C++ 프로그래밍 (초보자를 위한). 문운당
'개발 > C++' 카테고리의 다른 글
C++ 열거형, 구조체, 공용체2 (0) | 2022.05.04 |
---|---|
C++ 열거형, 구조체, 공용체 (0) | 2022.05.04 |
C++의 고급 기능 (0) | 2022.04.08 |
C++ 배열3 (0) | 2022.04.06 |
C++ 배열2 (0) | 2022.04.05 |