Dynamic Array
동적 배열
- Dynamic Binding(동적 바인딩)* 방식으로 메모리를 할당받은 배열을 의미한다.
- Static Binding을 통해 메모리를 할당받는, 일반적으로 선언된 배열보다 메모리 효율이 높다.
- 실행시간 동안에 메모리를 할당받으므로 프로그램 실행효율은 정적 바인딩 방식보다 떨어진다.
* Dynamic Binding (동적 바인딩)
- 컴파일 시간이 아닌 실행시간 동안 메모리를 필요한만큼 할당할 수 있게하는 기법이다.
- 반의어는 Static Binding (정적 바인딩)이다.
Operator : new, delete (new, delete 연산자를 통한 동적 배열 생성)
// 일반형
dataType* pointerName = new dataType[numElements];
delete [] pointerName;
// 사용 예시
int* pSum = new int[10];
for(int i = 0; i < 10; i++)
cin >> pSum[i];
cout << "첫 번째 원소: " << pSum[0] << endl;
cout << "세 번째 원소: " << *(pSum + 2) << endl; // 다다음 원소를 출력 (여기서, 2는 2Byte를 의미하는 것이 아니다!)
pSum = pSum + 2;
cout << "현재 pSum은 세 번째 원소인 " << pSum[0] << " 을 가리키고 있다." << endl; // 실제로 pSum[2]가 출력된다!
pSum = pSum - 2; // 메모리 해제 전에는 꼭 원래 자리로 되돌려놔야 한다!
delete [] pSum;
- new 연산를 통한 memory allocation,
delete를 통한 memory freeing이 이루어지게 된다.
- 일반적으로 선언된 배열과 마찬가지로,
new를 통해 메모리를 할당받은 포인터는 배열의 첫 번째 원소의 주소를 가리키고 있으므로,
포인터 변수이름은 그 자체로 주솟값으로 쓰이기도 한다.
(일반적인 배열과 다를 바가 없는데, 이는 C와 C++에서는 배열을 구현할 때 포인터를 이용하기 때문이다.)
※ 배열 변수의 기본적인 표기 방법
arrayName // is iff below:
arrayName[0]
arrayName[i] // is iff below:
*(arrayName+i)
- 위 코드에서 "pSum = pSum + 2"라는 표현은 동적으로 할당받은 포인터 변수에서만 허용되는 표현이며
('변수'이기 때문에 값 변경이 가능하다.)
일반적인 배열 이름으로는 이렇게 표현할 수 없다. (일반적인 배열 이름값은 변경할 수 없다!)
- 할당된 메모리 블럭에 얼마나 많은 원소가 들어 있는지는 전적으로 프로그래머가 파악하고 있어야 한다.
컴파일러는 동적 배열을 할당받은 포인터가 배열의 첫 번째 원소를 가리키고 있다는 사실을 자체적으로 판단할 수 없기 때문이다.
- delete [] 연산자로 올바르게 메모리를 해제할 수 있도록 프로그램은 내부적으로 대입되는 메모리의 양을 추적하지만
프로그래머는 그 정보를 사용할 수 없다.
C++ 컴파일러는 해당 포인터 변수를 배열 주소로 해석하지 않기 때문이다.
sizeof(arrayName); // 전체 배열의 크기를 반환한다.
sizeof(pointerName); // 포인터 변수의 크기를 반환한다. (동적 배열의 크기 X)
Reference: Stephen Prata, C++ Primer Plus 6th Edition, Pearson, 2011