2010-04-17 6 views
2
int arr[ 5 ] = { 0 }; 

int i = 8; // out of bounds 

arr[ i ] = 8; 

이 상황에서 충돌에서 코드를 보호하는 방법이 경우에 (내가 < 0 || I> 5) 나는 또한에 SEH에 대해 알고난 그냥 내가 좋아하는 확인할 수 있다는 것을 알고

.... 비주얼 스튜디오,하지만 그것은 솔루션을 작동하지 않는 것 같습니다.

__try { /* code */ } 

__except(GetExceptionCode() == EXCEPTION_ARRAY_BOUNDS_EXCEEDED) 

이것은 작동하지 않습니다. SEH가 0으로 나눌 수있는 상황에서 작업하는 것을 볼 때, 보호 된 페이지에 액세스 ... 내 프로그램을 충돌로부터 어떻게 보호 할 수 있습니까?

답변

4

SEH가이 사실을 알아 차릴 것이라는 보장은 없습니다. 액세스를 감지하는 하드웨어에 따라 다르며, 이는 잘못된 어레이 액세스에 대해서는 발생하지 않습니다. 잡기를 원할 경우 배열 대신 표준 C++ std::vector 컨테이너를 사용하고 [] 연산자가 아닌 at() 멤버 함수를 통해 액세스하십시오. 액세스가 유효하지 않은 경우 표준 C++ 예외가 발생합니다.

+0

안녕하세요 닐 버터 워스입니다. 나는 컨테이너에 대해 알고 있고 가능하면 그것을 사용하지만 배열이 필요할 때 어떻게해야합니까? –

+2

@David 다른 주석에서 말했듯이, 배열을 사용할 필요가 없을 것입니다. 제 자신의 코드에서는 사용하지 않습니다. 그러나 필요하다고 느끼면 액세스 위반 여부를 확인할 방법이 없습니다. –

+0

Valgrind가 범위를 벗어난 액세스를 감지 할 수 있습니까? – fredoverflow

1

std :: vector와 같은 적절한 컨테이너를 사용하고 예외를 잡으시겠습니까?

+0

컨테이너에 대해 knwo하고 가능하면 그것을 사용하지만 배열이 필요할 때 어떻게해야합니까? –

2

자신을 보호 할 수는 없습니다. 원하는 경우 다른 언어를 사용해야합니다. C 및 C++에서는 안전한 코드를 작성하는지 직접 확인해야합니다.

대체가 구조체 내로 배열을 포장 할 수있다 ...

template<typename E, std::size_t s> 
struct array { 
    E &operator[](std::ptrdiff_t i) { 
    assert(i < s && "out of range!"); 
    return d[i]; 
    } 
    E const &operator[](std::ptrdiff_t i) const { 
    assert(i < s && "out of range!"); 
    return d[i]; 
    } 

    typedef E underlying_array[s]; 
    underlying_array &raw() { return d; } 
    underlying_array const &raw() const { return d; } 

    E d[s]; 
}; 


array<int, 5> arr = { 0 }; 
arr[8] = 8; /* assert will ring */ 
foo(arr.raw()); /* pass as an int[5] */ 

클래스는 (a raw 기능이없는 단)도 boost 및 C++ 0X 의해 제공되지만, 에러 검사는 필요하지 않습니다.

0

당신은 몇 가지 옵션을 사용할 수 있습니다

  • 원시 배열 (사용 표준 : : 벡터 또는 부스트 : : 배열 대신)
  • 는 사용하지 않는를 사용하지 않는 C++

유일한 다른 옵션은 에 범위를 벗어나는 오류가없는 코드를 작성하는 것입니다.

아웃 오브 보를 정확하게 감지 할 수있는 방법은 없습니다 C++에서 원시 배열의 nds 오류.

가끔이 발생하는 액세스 위반을 catch 할 수는 있지만 올바른 프로그램이 아닙니다. 이전에 할당 된 메모리를 덮어 쓰고 프로그램의 다른 부분을 손상 시키면 다른 많은 경우에도 문제가 발생합니다.

관련 문제