함수 내의 배열은 안전한 지를 실제 코딩으로 확인해 보겠습니다. 아래의 fun_local() 함수에는 buff[] 배열 변수가 있습니다. main() 함수에서 fun_local()을 호출하면 어떻게 될까요? fun_local()은 새로운 buff[]를 1024*1024 크기로 계속 생성하게 됩니다.

#include <stdio.h>
#include <string.h>

static void fun_local( int count){

    char    buff[1024 * 1024];

    memset( buff, 0, sizeof( buff));
    printf(  "count=%d   %p\n", count, &(buff[0]));
    fun_local( count+1);
}

int main( void){

    fun_local( 1);

    return 0;
}

프로그램을 실행해 보면, 아래와 같이 결국 메모리 생성에 실패하고 프로그램은 종료 됩니다.

]$ ./test_array 
count=1   0xbe872af0
count=2   0xbe772ae0
count=3   0xbe672ad0
count=4   0xbe572ac0
count=5   0xbe472ab0
count=6   0xbe372aa0
count=7   0xbe272a90
Segmentation fault
]$

하드웨어 사양에 따라 시스템 에러를 발생하는 시간적인 차이가 있겠지만, 함수 내에 선언된 배열은 static 키워드를 사용하지 않으면 계속 실행 중에 할당 받는 다는 것을 알 수 있습니다. 생성된 배열의 주소 값이 계속 변동되지요? 이것은 신기한 것도 아니고 당연한 것입니다만, 때로 메모리 부족으로 시스템을 불안하게 하는 요소가 되므로 유의해야 합니다.

 

그렇다면 이번에는 배열 변수를 static으로 선언하겠습니다. static 키워드를 삽입하면 함수를 호출할 때마다 배열을 만드는 것이 아니라 프로그램 실행 중에 생성된 배열을 계속 사용하게 됩니다. static 키워드의 본연의 기능을 다하는 것이죠. 물론 아래의 예제는 재귀 호출에서 빠져 나오는 코드가 없어서 스택 오버가 발생하겠지만, 배열을 생성할 메모리가 부족해서 에러가 발생하지는 않습니다.

#include <stdio.h>
#include <string.h>

static void fun_local( int count){

    static char    buff[1024 * 1024];

    memset( buff, 0, sizeof( buff));
    printf(  "count=%d   %p\n", count, &(buff[0]));
    fun_local( count+1);
}

int main( void){

    fun_local( 1);

    return 0;
}

실행해 보면 첫 번째 예제보다 실행 시간이 길다는 것과 배열의 주소가 같다는 것을 알 수 있습니다.

]$ ./test_array 
count=1   0x15c7d
count=2   0x15c7d
count=3   0x15c7d
count=4   0x15c7d
count=5   0x15c7d
count=6   0x15c7d
count=7   0x15c7d
count=8   0x15c7d
count=9   0x15c7d
count=10   0x15c7d
count=11   0x15c7d
        :

그러므로 자주 호출되는 함수이거나 내부 배열의 크기가 매우 크다면 static 키워드를 사용하여 안정성을 높이는 것이 좋습니다.