如何在这种情况下保护代码免于崩溃

时间:2010-04-17 10:56:30

标签: c++ windows visual-studio-2008 exception-handling

int arr[ 5 ] = { 0 };

int i = 8; // out of bounds

arr[ i ] = 8;

我知道如果(i< 0 || i> 5)我可以检查我喜欢....

我也了解Visual Studio中的SEH,但它看起来不是解决方案。

__try { /* code */ } 

__except(GetExceptionCode() == EXCEPTION_ARRAY_BOUNDS_EXCEEDED)

这不起作用。正如我看到SEH在分为0的情况下工作,访问受保护的页面......如何保护我的程序免受崩溃?

4 个答案:

答案 0 :(得分:4)

无法保证SEH会捕获这一点 - 这取决于您的硬件是否检测到访问权限,这对于所有无效的数组访问都不会发生。如果您想确保捕获它,请使用标准C ++ std::vector容器而不是数组,并通过其at()成员函数而不是[]运算符访问它 - 这将如果访问无效,则引发标准C ++异常。

答案 1 :(得分: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] */

该类由boost和C ++ 0x提供(但是,没有raw函数),但不需要进行错误检查。

答案 2 :(得分:1)

使用像std :: vector这样的正确容器并捕获异常?

答案 3 :(得分:0)

您有几个选择:

  • 不要使用原始数组(使用std :: vector或boost :: array)
  • 不要使用C ++

唯一的另一种选择是编写不包含任何越界错误的代码

绝对没有办法在C ++中可靠地检测原始数组上的越界错误。

您可以捕获有时发生的访问冲突,但这不会为您提供正确的程序。在许多其他情况下,你仍然会超出范围,覆盖以前分配的内存并破坏程序的其他部分。