Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 배열 감쇠(Array Decay)란? 개념부터 방지 방법까지

C++에서 배열 감쇠(Array Decay)란 배열의 타입과 차원(크기) 정보가 손실되어 일반 포인터로 변환되는 현상을 말합니다. 배열을 함수에 값이나 포인터 형태로 전달하면 배열 전체가 복사되는 것이 아니라 배열의 첫 번째 요소 주소만 전달됩니다. 따라서 함수 내부에서 sizeof() 연산자를 사용하면 원래 배열의 크기가 아닌 포인터의 크기가 반환됩니다.

배열 감쇠 예제

다음은 C++에서 배열 감쇠가 발생하는 상황을 보여주는 예제입니다.

#include<iostream>
using namespace std;
void DisplayValue(int *p) {
    cout << "값으로 전달했을 때의 배열 크기 : ";
    cout << sizeof(p) << endl;
}
void DisplayPointer(int (*p)[10]) {
    cout << "포인터로 전달했을 때의 배열 크기 : ";
    cout << sizeof(p) << endl;
}
int main() {
    int arr[10] = {1, 2};
    cout << "배열의 실제 크기 : ";
    cout << sizeof(arr) << endl;
    DisplayValue(arr);
    DisplayPointer(&arr);
    return 0;
}

실행 결과

배열의 실제 크기 : 40
값으로 전달했을 때의 배열 크기 : 8
포인터로 전달했을 때의 배열 크기 : 8

int형 요소 10개로 구성된 배열은 4바이트 × 10 = 40바이트입니다. 그러나 함수로 전달된 순간 배열은 포인터로 변환되기 때문에 sizeof() 결과가 64비트 시스템 기준 8바이트(포인터 크기)로 출력됩니다. 32비트 시스템에서는 4바이트가 출력됩니다.

배열 감쇠를 방지하는 방법

배열 감쇠는 다음 두 가지 방법으로 예방할 수 있습니다.

  • 배열 크기를 별도의 매개변수로 전달: 함수에 배열과 함께 배열의 크기를 인자로 넘기고, 배열 매개변수에는 sizeof()를 사용하지 않습니다.

  • 참조(reference)로 배열 전달: 배열을 참조 형태로 함수에 전달하면 배열이 포인터로 변환되는 것을 막을 수 있으므로 배열 감쇠가 발생하지 않습니다.

배열 감쇠 방지 예제

다음은 참조를 사용하여 배열 감쇠를 방지하는 예제입니다.

#include<iostream>
using namespace std;
void Display(int (&p)[10]) {
    cout << "참조로 전달했을 때의 배열 크기 : ";
    cout << sizeof(p) << endl;
}
int main() {
    int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    cout << "배열의 실제 크기 : ";
    cout << sizeof(arr) << endl;
    Display(arr);
    return 0;
}

실행 결과

배열의 실제 크기 : 40
참조로 전달했을 때의 배열 크기 : 40

배열을 int (&p)[10]처럼 참조로 전달하면 타입과 크기 정보가 그대로 유지되므로 sizeof()가 정확한 배열 크기인 40바이트를 반환합니다. 다만 이 방식은 배열의 크기가 고정된다는 점에 유의해야 합니다. 서로 다른 크기의 배열을 유연하게 처리하려면 템플릿을 활용하거나 std::array, std::vector 같은 표준 컨테이너를 사용하는 것이 좋습니다.