동적 배열이란 크기가 고정되지 않은 배열을 의미한다. (이름 그대로 단순하다!)보통 우리가 흔히 말하는 배열은 동적(Dynamic)의 반대인 정적(Static) 즉, 정적배열을 의미한다. 정적배열은 크기가 고정되어 있어 데이터를 크기 만큼만 저장할 수 있다.
출처: https://noahlogs.tistory.com/29 [지푸라기 개발자:티스토리]
고정 크기 배열의 한계: 정적 배열은 크기가 고정되어 있어, 배열을 선언할 때 미리 크기를 지정해야 합니다. 이는 사용량을 정확히 예측하기 어려운 경우 문제가 됩니다.
동적 배열의 장점: 동적 배열은 필요한 만큼 크기를 조정할 수 있습니다. 초기에는 작은 크기로 시작했다가 필요에 따라 배열의 크기를 늘릴 수 있습니다. 이는 메모리 사용의 효율성을 높이고 프로그램의 유연성을 증가시킵니다.
동적 메모리 할당: 동적 배열은 실제로 필요할 때 메모리를 할당하므로, 처음부터 큰 배열을 할당하는 것보다 메모리 사용이 효율적입니다. 필요하지 않은 메모리를 미리 할당하지 않기 때문에 메모리 낭비를 줄일 수 있습니다.
대규모 데이터: 고정 크기 배열은 스택 메모리에 할당되기 때문에, 크기가 큰 배열을 사용할 경우 스택 오버플로우가 발생할 수 있습니다. 동적 배열은 힙 메모리에 할당되므로, 훨씬 큰 배열을 사용할 수 있습니다.
런타임 데이터: 많은 경우, 배열의 크기를 컴파일 타임에 알 수 없습니다. 동적 배열은 프로그램이 실행되는 동안 필요한 크기를 결정하고 할당할 수 있도록 합니다.
일반화된 코드: 동적 배열은 다양한 크기의 데이터 집합을 처리할 수 있는 일반적인 코드를 작성하는 데 유용합니다. 예를 들어, 데이터베이스 결과나 사용자 입력 등 다양한 크기의 데이터를 처리할 때 유용합니다.
#include <stdlib.h>
// 동적배열 (가변배열)
struct Array
{
int* pData;
int Limit;
int Current;
};
void Init(Array* _Arr)
{
_Arr->Limit = 2;
_Arr->Current = 0;
_Arr->pData = (int*)malloc(sizeof(int) * _Arr->Limit);
}
void Push(Array* _Arr, int _Data)
{
// 현재 동적할당한 공간이 꽉 찬 경우
if (_Arr->Limit <= _Arr->Current)
{
// 기존 Limit 의 2배를 동적할당한다.
// 16바이트 할당
int* pNewData = (int*)malloc(_Arr->Limit * 2 * sizeof(int));
// 기존 공간의 데이터를, 새로운 공간으로 이동시킨다.
for (int i = 0; i < _Arr->Current; ++i)
{
pNewData[i] = _Arr->pData[i];
}
// 기존 공간을 메모리 해제한다.
free(_Arr->pData);
// 동적배열이 새로운 공간을 가리키게 한다.
_Arr->pData = pNewData;
// 최대 개수를 갱신한다.
_Arr->Limit *= 2;
}
_Arr->pData[_Arr->Current++] = _Data;
}
void Release(Array* _Arr)
{
free(_Arr->pData);
_Arr->pData = nullptr;
_Arr->Limit = 0;
_Arr->Current = 0;
}
int main()
{
Array arr = { };
Init(&arr);
Push(&arr, 100); // pData[0] = 100
Push(&arr, 200); // pData[1] = 200
Push(&arr, 300); // 배열 크기 2배 증가 후, pData[2] = 300
Push(&arr, 400); // pData[3] = 400
Push(&arr, 500); // 배열 크기 2배 증가 후, pData[4] = 500
Release(&arr);
return 0;
}