1. 배열 색인의 유효성 체크

char str[8]; 

이 경우 str 배열의 범위를 벗어난 str[8]을 사용하여 값을 대입하면 어떤 일이 발생할까?
      
      [ 문법 오류가 아니다. ]
       - str[8]이라는 표현은 배열 문법이긴 하지만 메모리 주소를 표현하는 하나의 형식이기 때문에 
         컴파일러는 해당 주소에 대한 유효성 검사를 하지 않는다. 따라서 str[8]이 명백하게 str 배열의 범위를
         벗어났다고 해도 컴파일러는 이 명령문에 대해 오류 처리를 하지 않는다.

       - 이런 경우 오류 처리를 하지 않기 때문에 컴파일이 잘 된다. 하지만 프로그램의 메모리 할당 구조에 따라
         운 좋게 아무 문제 없이 동작하거나, 오류가 나서 프로그램이 중단되거나 혹은 오류는 발생하지 않지만
          원하는 결과가 나오지 않는 경우가 생길 수 있다.  -> 프로그램에 버그(Bug)가 생기게 된다

      [ 개발자가 직접 오류 처리를 해야 함 ]
       - if(index >= 0 && index <= 7) str[index]= '5'; 
       - c언어 컴파일러가 모든 상황에 대해 판단하지 못한다면 이런 식으로 개발자가 직접 색인에 대한 유효성을
         판단하는 것이 옳다.


2. 배열의 범위를 넘어서 사용한다면?

 

#include<stdio.h>

int main(){
    char str[10];
    fgets(str, 50, stdin); // 두번째 인자에 10을 사용해야 하지만 버그를 만들기 위해 50을 사용
    
    printf("input string : %s\n", str);
    return 0;
}

이 예제어서 사용된 str배열은 최대 9개의 문자열을 입력받아야 정상적으로 문자열을 처리할 수 있다.

 

[ 정상 수행 ]

 

[ Bug 발생 ]

- 사용자가 str배열의 범위를 초과하는 16개의 문자를 입력하면 이처럼 fgets와 printf는 정상 동작했지만
   이 프로그램은 문자열을 출력한 후 오류가 발생하며 중단되었다.
- 사실 처음 메모리를 초과하는 시점인 fgets() 함수에서 오류가 나야 하지만 해당 오류가 치명적인 종료 상황을
  만들지 않아서 운 좋게 진행된 것이다. 
   -> 이처럼 오류와 상관없는 지점인 프로그램의 마지막 부분에서 오류가 발생하기 때문에 오류를 찾는 입장에서
        이런 메모리 관련 버그는 더 찾기 어렵다.


3. 지역 변수들의 메모리 할당 방법

 

2번의 코드를 아래처럼 수정한다.

#include<stdio.h>

int main(){
    char str[10];
    char dummy[32] = {0,};
    fgets(str,50,stdin); // 2번째 인자에 10을 사용해야 하지만 버그를 만들기 위해 50 사용
    
    printf("input string : %s\n", str);
    return 0;
}

위 코드는 버그 상황이긴 하지만 더 이상 오류가 발생하지 않고 잘 동작한다.
-> 범위를 벗어나는 문자를 입력받아 str배열의 저장 범위를 초과하더라도 str 변수 아래에 선언된 dummy 배열에
     저장되어 정상적으로 동작하는 것처럼 보이는 것이다. 즉, 지역 변수들은 메모리에 순차적으로 나열되기 때문에
     str 변수의 영역을 넘어서게 되면 dummy 변수가 영향을 받게 된다.

 

[ 실행 결과 ]

str배열의 영역을 초과했지만 정상적으로 동작

 

실제 얼마나 초과되는지 확인 코드를 추가해서 확인해 보자.

#include<stdio.h>

int main(){
    char str[10];
    char dummy[32] = {0,};
    fgets(str, 50, stdin);
    
    printf("input string : %s\n", str);
    printf("dummy : %s\n", dummy);
    return 0;
}

[ 실행 결과 ]

[ printf가 정상적으로 문자열을 출력한 이유 ]

- printf함수의 %s 옵션은 사용자가 지정한 주소에서 시작하여 'NULL문자(\0)'가 나올 때까지 계속 문자를 출력하기
  때문에 str 배열의 범위를 벗어났는지는 체크하지 않는다.

 


 [ 결론 ]

  - 지역 변수로 선언된 배열은 다른 지역 변수 or 배열과 순차적으로 메모리에 나열되기 때문에 자신의 영역을 벗어나
    면 다른 지역 변수들에게 영향을 미치게 된다. 따라서 이런 문제가 발견되었는데 프로그램이 오류가 없이 동작
    한다고 해서 그냥 둔다면 나중에 버그로 고생하게 될 것이다.

'C,C++' 카테고리의 다른 글

C++ 멤버 초기화 리스트  (0) 2022.04.10
C++ 가상 함수(virtual function)  (0) 2022.04.09
c++에서 string 클래스를 이용한 문자열 사용 ( getline() )  (0) 2022.03.12
c언어 문자열  (0) 2022.02.04
이중포인터  (0) 2022.02.03

+ Recent posts