开发者

How to protect code from crashes in this situation

开发者 https://www.devze.com 2022-12-27 18:33 出处:网络
int arr[ 5 ] = { 0 }; int i = 8; // out of bounds arr[ i ] = 8; I know that I can just check i like this if( i < 0 || i > 5 ) ....
int arr[ 5 ] = { 0 };

int i = 8; // out of bounds

arr[ i ] = 8;

I know that I can just check i like this if( i < 0 || i > 5 ) ....

I also know about SEH in Visual Studio, but it looks li开发者_StackOverflow中文版ke not working solution.

__try { /* code */ } 

__except(GetExceptionCode() == EXCEPTION_ARRAY_BOUNDS_EXCEEDED)

This is not working. As I see SEH working in situations like divide to 0, access protected pages ... How can I protect my program from crashes?


There is no guarantee that SEH will catch this - it depends on your hardware detecting the access , which does not happen for all invalid array accesses. If you want to be sure of catching it, use the standard C++ std::vector container instead of an array, and access it via its at() member function, rather than the [] operator - this will raise a standard C++ exception if the access is invalid.


You cannot protect yourself from this. If you want, you have to use another language that checks for you. C and C++ demand that you check yourself that you write safe code.

An alternative may be to wrap the array into a struct...

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] */

That class is provided by boost and C++0x too (however, without a raw function), but error checking is not required for them.


Use proper containers like std::vector and catch the exceptions?


You have a couple of options:

  • don't use raw arrays (use std::vector or boost::array instead)
  • don't use C++

the only other option is to write code that does not contain any out-of-bounds errors

There is absolutely no way to reliably detect out-of-bounds errors on raw arrays in C++.

You could just catch the access violation that sometimes occurs, but that won't give you a correct program. You'll still go out of bounds in many other cases, overwriting previously allocated memory and corrupting other parts of your program.

0

精彩评论

暂无评论...
验证码 换一张
取 消