배열 범위 체크 :: 2007/08/01 16:41



C/C++언어는 기본적으로 배열에 대해서 범위 체크를 하지 않습니다. 여러가지 이유가 있겠지만 주된 이유는 속도 때문일 겁니다. 아무래도 첨자 검사를 위해서는 추가적인 코드가 들어가야 할테니까요. 그런데 이런 속도 상의 손해를 감수하고도 꼭 반드시 배열 범위를 검사해야 하는 경우가 있습니다. 바로 외부 데이터를 읽어 들이는 과정입니다. 메모리 상에서 내부적으로 조작하는 데이터야 버그와 해킹이 아닌 이상 신뢰할 수 있는 값을 항상 제공하겠지만, 외부의 파일이나, 네트워크 스트림의 내용은 언제든지 위, 변조될 가능성이 있습니다. 오류로 잘못 읽어지는 경우도 있겠죠. 따라서 이러한 곳에는 반드시 범위 검사를 넣어야 합니다. 그래야 안전하죠.

배열이 한, 두개인 경우야 수동으로 범위검사를 할 수 있겠지만, 세 개만 넘어가도 더 이상 수동으로 하기 힘들어 집니다. 또한 오류 발생 가능성도 높죠. 이러한 경우에 사용할 수 있는 간단한 템플릿 클래스가 아래 나와있습니다. 이 클래스는 배열과 호환되는 클래스로 내부적으로 크기 정보를 가지고 범위 검사를 수행합니다. 범위를 벗어나면 EOutOfRange 예외를 던집니다. T에는 배열을 저장할 타입을, size에는 해당 배열 크기를 집어넣으면 됩니다.
아래는 예외 클래스와 CFixedArray를 사용하는 샘플 코드 입니다.
요즘 프로그램에서 기초적인 형태의 배열을 사용하는 경우는 거의 없습니다. 대부분 벡터나 잘 포장된 형태의 가변 길이 배열을 지원하는 켄테이너 클래스를 사용하죠. 프로그램의 버그를 줄이고 싶다면 이러한 형태의 컨테이너 클래스를 사용하는 것이 좋은 습관입니다. 결론은 별로 그닥 유용한 코드는 아니라는 것이죠. ㅋㅋㅋㅋ


스폰서
글타래

  • 2주간 인기 글
  • 2주간 인기글이 없습니다.
Trackback Address :: http://jiniya.net/tt/trackback/551
  • Gravatar Image.
    풀리비 | 2007/08/07 00:47 | PERMALINK | EDIT/DEL | REPLY

    안녕하세요. 종종 들어와 좋은 글 보고 갑니다.
    코드위즈님께서 마지막에 강조하신 것과 제 생각은 다릅니다. 컨테이너 클래스를 유용하게 사용하면 좋지만, 그것의 한계를 알고, 상황에 따라 적절히 사용할 수 있어야 합니다.
    게다가 vector와 같은 자료구조도 [] 연산자를 사용해 원소를 접근한다면 일반 배열에서 []연산자로 원소 참조하는 것과 다를 바 없이 위험합니다. 단지 더 안전한(예외를 던지는) at() 멤버 함수를 더 구비하였고, iterator로 원소를 접근하라고 권고할 뿐이지요. 이는 성능과 안전 사이의 선택에 대한 책임을 개발자에게 남긴 것입니다.
    가변 길이라 어쩔 수 없는 overhead를 가지는 vector를 극복하고자 하는 고민의 결과 중 하나가 boost::array (코드위즈님의 CFixedArray와 같은 목적, 다른 계기)라이브러리입니다. vector랑 다 같은데 고정크기 배열이라는 것만 다릅니다. 그래서 많은 STL 알고리즘에서 사용할 수 없지요... merge() 등..

    • Gravatar Image.
      codewiz | 2007/08/07 12:35 | PERMALINK | EDIT/DEL

      좋은 의견 감사합니다.
      저도 전적으로 풀리비님 말씀에 동의합니다.

      일반적인 상황에서는 대체적으로 가공되지 않은 배열보다는 컨테이너 객체를 사용하는 것이 좋은 선택입니다. 여러가지 이유가 있겠지만 제가 생각하는 두 가지 이유는 보통의 문제가 극도로 타임 크리티컬 하지 않다는 점과, 사람의 시간이 기계의 시간보다는 더 비싸다는 점입니다.

      물론 컨테이너를 사용함에 있어서는 풀리비님 말씀대로 각 컨테이너의 장단점을 살려서 사용해야 함은 두말할 필요도 없이 중요한 내용입니다.

Name
Password
Homepage
Secret