Как защитить код от сбоев в этой ситуации - PullRequest
2 голосов
/ 17 апреля 2010
int arr[ 5 ] = { 0 };

int i = 8; // out of bounds

arr[ i ] = 8;

Я знаю, что могу просто проверить, нравится ли мне это, если (i <0 || i> 5) ....

Я также знаю о SEH в Visual Studio, но похоже, что это не рабочее решение.

__try { /* code */ } 

__except(GetExceptionCode() == EXCEPTION_ARRAY_BOUNDS_EXCEEDED)

Это не работает. Как я вижу, SEH работает в таких ситуациях, как деление на 0, доступ к защищенным страницам ... Как я могу защитить свою программу от сбоев?

Ответы [ 4 ]

4 голосов
/ 17 апреля 2010

Нет гарантии, что SEH поймает это - это зависит от вашего оборудования, обнаруживающего доступ, что не происходит для всех недопустимых обращений к массиву. Если вы хотите быть уверенным в его перехвате, используйте стандартный контейнер C ++ std::vector вместо массива и получите к нему доступ через функцию-член at() вместо оператора [] - это вызовет стандартное исключение C ++, если доступ недействителен.

2 голосов
/ 17 апреля 2010

Вы не можете защитить себя от этого.Если вы хотите, вы должны использовать другой язык, который проверяет вас.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 функция), но проверка ошибок для них не требуется.

1 голос
/ 17 апреля 2010

Использовать правильные контейнеры, такие как std :: vector, и перехватывать исключения?

0 голосов
/ 17 апреля 2010

У вас есть несколько вариантов:

  • не использовать необработанные массивы (вместо этого используйте std :: vector или boost :: array)
  • не используйте C ++

единственный другой вариант - написать код, который не содержит каких-либо недопустимых ошибок

Абсолютно невозможно надежно обнаружить недопустимые ошибки в необработанных массивах в C ++.

Вы можете просто обнаружить нарушение прав доступа, которое иногда происходит, но это не даст вам правильную программу. Во многих других случаях вы будете выходить за пределы, перезаписывая ранее выделенную память и портя другие части вашей программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...