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);
}

실행 결과

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

위 실행 결과를 보면, 원래 배열은 int형 10개 요소로 구성되어 있어 크기가 40바이트(4바이트 × 10)입니다. 하지만 함수에 전달된 후에는 포인터의 크기인 8바이트(64비트 시스템 기준)로 표시되는 것을 확인할 수 있습니다. 이것이 바로 배열 감쇠입니다.

배열 감쇠를 예방하는 방법

C++에서 배열 감쇠를 방지하는 대표적인 방법은 다음 두 가지입니다.

  • 배열의 크기를 별도의 매개변수로 전달하고, 함수 내부에서 배열 매개변수에 대해 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);
}

실행 결과

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

실행 결과에서 볼 수 있듯이, 배열을 참조(int (&p)[10])로 전달하면 함수 내부에서도 원래 배열의 크기인 40바이트가 그대로 유지됩니다. 이처럼 참조 전달을 활용하면 배열의 타입과 크기 정보가 손실되지 않아 배열 감쇠를 효과적으로 방지할 수 있습니다.