C++ 강좌 5편. new, delete [최근 수정 2017.10.10]
1. C언어의 malloc & free
우리가 C언어를 배울 때, malloc과 free란 녀석은 이미 만나본 적이 있습니다. malloc이란 함수는 '힙 영역에 메모리 공간을 할당할 수 있게 도와주는 함수'라고 말했었고, free 함수는 'malloc 함수 호출 시 할당되었던 메모리 공간을 전부 해제할 수 있게 도와주는 함수'라고 말한 적이 있었습니다. C언어 11강에서 보았던 예제를 다시 한번 보도록 하겠습니다.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int studentNum, totalScore=0;
int* studentScore;
int i;
printf("학생 수를 입력하세요: ");
scanf("%d", &studentNum);
studentScore = (int *)malloc(sizeof(int) * studentNum);
for(i=0; i<studentNum; i++) {
printf("%d번 학생의 점수: ", i + 1);
scanf("%d", &studentScore[i]);
totalScore += studentScore[i];
}
printf("모든 학생의 평균: %d\n", totalScore / studentNum);
free(studentScore);
return 0;
}
결과:
학생 수를 입력하세요: 5
1번 학생의 점수: 1
2번 학생의 점수: 2
3번 학생의 점수: 3
4번 학생의 점수: 4
5번 학생의 점수: 5
모든 학생의 평균: 3
계속하려면 아무 키나 누르십시오 . . .
주목하셔야 할 부분은 12행의 malloc과 21행의 free 함수입니다. 이렇게 malloc 함수로 동적 할당하고, free로 그 동적 할당한 메모리를 해제해주었는데 이것을 C++에서는 new와 delete가 대신하게 되었습니다.
2. new & delete
그렇다면 C언어에서의 malloc과 delete가 어떻게 변했을까요? 먼저 new 연산자부터 살펴보도록 합시다.
...
// studentScore = (int *)malloc(sizeof(int) * studentNum);
studentScore = new int[studentNum];
...
감이 오시나요? new 연산자는 단일 객체를 동적 할당하고 싶을 때는 'new 자료형', 객체의 배열을 동적 할당 하고 싶을 때는 'new 자료형[길이]'와 같이 사용됩니다. 바로 아래와 같이 말이죠.
int* ptr1 = new int(3);
double* ptr2 = new double[3];
float* ptr3 = new float[10];
참고로, 1행은 길이 3의 객체의 배열을 할당하는 것이 아닙니다. 자세히 보시면 소괄호로 둘러싸여 있는데, 이는 new 연산자로 메모리 공간에 할당하고 그 값을 3으로 초기화 한다는 것입니다.
...
// free(studentScore);
delete []studentScore;
...
delete 연산자는 new 연산자로 할당된 객체의 메모리를 해제할 때 사용합니다. 'delete 포인터'와 같이 사용하며, 포인터는 할당을 해제할 객체를 가리키는 포인터를 의미합니다. 만약, 포인터가 객체 배열을 가리키고 있는 경우 포인터 앞에 빈 대괄호를 끼워 넣습니다. 'delete []포인터'와 같이 말이죠.
int* ptr1 = new int(3);
double* ptr2 = new double[3];
float* ptr3 = new float[10];
...
delete ptr1;
delete []ptr2;
delete []ptr3;
malloc과 free로 구현한 예제를 이번에는 new와 delete로 구현해보도록 하겠습니다.
#include <iostream>
using namespace std;
int main()
{
int studentNum, totalScore=0;
int* studentScore;
int i;
cout << "학생 수를 입력하세요: ";
cin >> studentNum;
studentScore = new int[studentNum];
for(i=0; i < studentNum; i++) {
cout << i + 1 << "번 학생의 점수: ";
cin >> studentScore[i];
totalScore += studentScore[i];
}
cout << "모든 학생의 평균: " << totalScore / studentNum << endl;
delete []studentScore;
return 0;
}
결과:
학생 수를 입력하세요: 5
1번 학생의 점수: 1
2번 학생의 점수: 2
3번 학생의 점수: 3
4번 학생의 점수: 4
5번 학생의 점수: 5
모든 학생의 평균: 3
계속하려면 아무 키나 누르십시오 . . .
코드에서 12행을 살펴보시면 new 연산이 등장했습니다. studentNum에 5라는 값이 들어왔다고 가정하면, 길이가 5인 int형 배열을 동적 할당한 것입니다. 그리고 21행을 보시면 int형 배열이기 때문에 []studentScore로 해제해주어야만 합니다. 여기까지 이해하셨나요? 만약 이해가 되지 않으셨더라도, 배운 내용을 복습 겸 다시 살펴보면서 차근차근 나아가셔도 좋습니다.
malloc/free와 new/delete는 어떤 차이가 있죠?
malloc/free |
new/delete |
함수 | 연산자 |
초기값을 원하는 값으로 할당할 수 없음 |
할당과 초기화를 한꺼번에 할 수 있음 |
필요한 크기는 바이트 단위로 지정해주어야 함 |
필요한 크기는 컴파일러에 의해 계산됨 |
할당된 메모리는 realloc을 통해 크기 변경이 가능 |
재할당이 불가능함 / STL의 컨테이너 라이브러리인 vector를 사용하는 것이 대안이 될 수 있음 |
할당 실패 시 NULL을 반환함 |
할당 실패 시 std::bad_alloc 예외를 던짐 |
메모리 할당/해제에 초점이 맞추어져 있기 때문에 객체 생성/제거 시 생성자/소멸자 호출 안됨 |
객체 생성/제거 시 생성자/소멸자 호출 |
이번 강좌는 여기서 마치도록 하겠습니다. 수고하셨습니다.
다음 강좌에서는 구조체의 확장에 대해 배워보도록 하겠습니다.
'프로그래밍 관련 > C++' 카테고리의 다른 글
C++ 강좌 7편. 클래스(class) (25) | 2012.11.04 |
---|---|
C++ 강좌 6편. 구조체의 확장 (28) | 2012.11.01 |
C++ 강좌 4편. 함수 오버로딩(Function Overloading) [최근 수정 2017.10.10] (19) | 2012.10.28 |
C++ 강좌 3편. 네임스페이스(namespace) [최근 수정 2017.05.21] (17) | 2012.10.25 |
C++ 강좌 2편. 기본 입출력 함수 둘러보기 [최근 수정 2017.05.20] (17) | 2012.10.23 |