Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 37, средняя оценка - 4.68
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
#1

Проверить на выход за границы массива - C++

05.05.2013, 12:39. Просмотров 5802. Ответов 44
Метки нет (Все метки)

ПРивет, помогите пожалуйста, пишу класс - динамический массив, в перегрузке оператора [] нужно проверить на выход за границы, но не знаю как правильно использовать try, catch, throw.
C++
1
2
3
4
5
6
7
8
9
10
11
template <class T, int size>
T & Array<T, size> :: operator [](int index) {
    try {
    if (index < 0 || index >= currentSize)
        throw out_of_range("Index was out of range");
    }
    catch(...) { // что тут писать чтобы поймать из throw
        cout << "error";
    }
    return aPtr[index]; // и как быть тут куда вставить эту строку
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.05.2013, 12:39
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Проверить на выход за границы массива (C++):

Выход за границы массива - C++
Выхожу за пределы массива, но вот только не понимаю как. #include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; const...

Массивы: Проверка на выход за границы массива - C++
Здравствуйте! Пишу код хождения коня по шахматной доске. Конь пока стоит на одном месте и ходит по кругу. Как можно реализовать проверку на...

Исправить выход за границы двумерного динамического массива - C++
Уважаемые форумчане, помогите, проблема в том, что пишет ошибку после выполнения функции вывода массива, вот код //распечатка матрицы ...

Почему происходит выход за границы массива в функции Analyze()? - C++
#include &quot;Analyzer.h&quot; #include &quot;HashTable.h&quot; #include &lt;iostream&gt; #include &lt;iomanip&gt; using namespace std; ...

При вызове функции необработанное исключение, выход за границы массива - C++
bool checkprocessed(point data,int xx,int yy,int wind) { bool mark=false; int s=0; for(int k=xx; k&lt;xx+wind;k++){ for(int...

Выход итератора за границы list - C++
почему у меня падает программа, когда пытаюсь ввести отсортированные элементы в другой list ??? list&lt;char&gt;ch; list&lt;char&gt;rev; ...

44
Кудаив
329 / 406 / 24
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 2
05.05.2013, 12:45 #2
C++
1
2
3
4
5
6
7
    try {
    if (index < 0 || index >= currentSize)
        throw out_of_range("Index was out of range");
    }
    catch(const out_of_range& oor) { // что тут писать чтобы поймать из throw
        cout << oor.what();
    }
1
Убежденный
Ушел с форума
Эксперт С++
15697 / 7207 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
05.05.2013, 12:51 #3
1) Ловить исключения - это забота клиентского кода. Поэтому просто бросайте out_of_range,
try и catch здесь не нужны. Только задекларируйте в документации класса или самого метода,
что он может бросать данное исключение, чтобы для клиента это не стало сюрпризом.

2) Размеры обычно задаются типом size_t, а не int. Это общепринятая практика, к тому же
снижается количество потенциальных проблем при переносе на другую платформу (64-бита).

3) Не забудьте написать const-вариацию перегруженного оператора индексации.
1
OhMyGodSoLong
05.05.2013, 13:28
  #4

Не по теме:

Релизные версии STL не проверяют границы. /discuss

0
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 14:07  [ТС] #5
Цитата Сообщение от Убежденный Посмотреть сообщение
1) Ловить исключения - это забота клиентского кода. Поэтому просто бросайте out_of_range,
try и catch здесь не нужны. Только задекларируйте в документации класса или самого метода,
что он может бросать данное исключение, чтобы для клиента это не стало сюрпризом.
тогда придется в main'е делать try catch ? хотя можно написать функции в которых будут создаваться объекты и там уже try catch
0
Кудаив
329 / 406 / 24
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 2
05.05.2013, 14:17 #6
Цитата Сообщение от Kreativ Посмотреть сообщение
1) Ловить исключения - это забота клиентского кода. Поэтому просто бросайте out_of_range,
try и catch здесь не нужны. Только задекларируйте в документации класса или самого метода,
что он может бросать данное исключение, чтобы для клиента это не стало сюрпризом.
это советы не для новичка, делай как тебе удобно
1
Убежденный
Ушел с форума
Эксперт С++
15697 / 7207 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
05.05.2013, 14:21 #7
Цитата Сообщение от Kreativ Посмотреть сообщение
тогда придется в main'е делать try catch ? хотя можно написать функции в которых будут создаваться объекты и там уже try catch
Да. Выбор стратегии зависит от конкретных условий и сценариев использования класса.
Одни ошибки можно перехватить и обработать локально, после чего продолжить выполнение,
другие лучше не "прокидывать" и не маскировать, а выдать пользователю сообщение и
завершить работу программы.
1
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 16:15  [ТС] #8
у меня опять встал вопрос, я перегружаю оператор = , в нем необходимо выделить память, наверное надо поставить в try - catch, правильно ли я делаю:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template <class T, size_t size>
Array<T, size> & Array<T, size> :: operator = (const Array<T, size> &arrayForAssign) {
    if (aPtr != nullptr) // нужно ли ставить проверку, если массив которому я присваиваю не инициализирован  
        delete [] aPtr;  
    currentSize = arrayForAssign.currentSize;
    maxSize = arrayForAssign.maxSize;
    try {
        aPtr = new T[currentSize]; // new сам же выбрасывает bad_alloc
        for (size_t i = 0; i < currentSize; i++) 
            aPtr[i] = arrayForAssign.aPtr[i];
    }
    catch(bad_alloc &exc) {
        cout << exc.what() << endl;
    }
    return *this;
}
где мне обрабатывать искл. внутри перегруженного оператора или нет?
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
05.05.2013, 16:18 #9
Цитата Сообщение от Kreativ Посмотреть сообщение
где мне обрабатывать искл. внутри перегруженного оператора или нет?
нет
0
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 16:25  [ТС] #10
сделал так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template <class T, size_t size>
Array<T, size> & Array<T, size> :: operator = (const Array<T, size> &arrayForAssign) {
    if (this != &arrayForAssign) {
        if (aPtr != nullptr)
            delete [] aPtr;   
        currentSize = arrayForAssign.currentSize;
        maxSize = arrayForAssign.maxSize;
        aPtr = new T[currentSize];
        for (size_t i = 0; i < currentSize; i++) 
            aPtr[i] = arrayForAssign.aPtr[i];
    }
    return *this;
}
нужна ли проверка
C++
1
2
if (aPtr != nullptr)
            delete [] aPtr;
чтобы не очищать память пустого массива
и как быть если скажем память не выделилась, тогда мой массив останется пустым, его размеры изменятся
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
05.05.2013, 16:26 #11
Цитата Сообщение от Kreativ Посмотреть сообщение
нужна ли проверка
нет
Цитата Сообщение от Kreativ Посмотреть сообщение
и как быть если скажем память не выделилась, тогда мой массив останется пустым, его размеры изменятся
http://ru.wikipedia.org/wiki/%D0%98%..._copy-and-swap
1
Nick Alte
Эксперт С++
1640 / 1012 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
05.05.2013, 16:39 #12
Сообщать об исключении и тем более гасить его - совершенно не операторское дело. Его задача только "подчистить" что возможно и насколько возможно в данной ситуации и передать исключение дальше. Таким образом, порядок действий такой:
а) выделить память под новый массив, исключение при этом перехватывать не надо: если возникнет ошибка, то сам объект пока что в прежнем состоянии и никакие ресурсы не утекли.
б) переписать содержимое копируемого объекта в выделенную память, перехватывая исключения. Если при копировании одного из элементов будет выброшено исключение, уже надо освобождать ресурсы: в обратном порядке уничтожить уже заполненные элементы нового массива и освободить сам массив.
в) уничтожить содержимое старого массива и освободить его, после чего заменить новым массивом. Эта операция не должна приводить к исключительным ситуациям (если тип T сделан по уму и его деструктор не выбрасывает исключений).
При таком порядке действий операция либо завершится успешно, либо будет прервана исключением, а сам объект при этом останется в том же состоянии, в котором был до начала операции (т.н. "сильная" гарантия безопасности). Утечек при возникновении исключений такой оператор тоже не создаст.
2
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 17:11  [ТС] #13
Цитата Сообщение от Nick Alte Посмотреть сообщение
Если при копировании одного из элементов будет выброшено исключение, уже надо освобождать ресурсы: в обратном порядке уничтожить уже заполненные элементы нового массива и освободить сам массив.
затем в пункте В
Цитата Сообщение от Nick Alte Посмотреть сообщение
в) уничтожить содержимое старого массива и освободить его, после чего заменить новым массивом.
а так новый массив то пуст будет если будет выброшено исключение
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.05.2013, 17:15 #14
Третий пункт не выполняется, если во втором вылетает исключение.
1
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 17:40  [ТС] #15
Посмотрите пож-та, я сделал по пунктам:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template <class T, size_t size>
Array<T, size> & Array<T, size> :: operator = (const Array<T, size> &arrayForAssign) {
    if (this != &arrayForAssign) {
        T *ptr = new T[arrayForAssign.currentSize]; // 1 пункт
        size_t s = arrayForAssign.currentSize;
 
        try {      // 2 пункт
            for (size_t i = 0; i < arrayForAssign.currentSize; i++) {
                ptr[i] = arrayForAssign.aPtr[i];
            }
 
            delete [] aPtr;  // 3 пункт если в копировании исключ не сгенерировалось
            currentSize = s;
            maxSize = arrayForAssign.maxSize;
            aPtr = new T[currentSize];
            for (size_t i = 0; i < currentSize; i++) 
                aPtr[i] = ptr[i];
            
        }
        catch(...) { // а что тут ловить?
            delete [] ptr;   
        }  
        return *this;
    }
    return *this;
}
Добавлено через 10 минут
перед catch забыл еще удалить ptr
0
05.05.2013, 17:40
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.05.2013, 17:40
Привет! Вот еще темы с ответами:

Выход за границы. как исправить??? - C++
Суто проги в том, чтобы из 2х массивов создать третий элементами которого я вляются совпавшие элементы первых 2х Например: 1 2 3 4 5 ...

Почему происходит выход за границы? - C++
2 игрока берут из своих колод по 1-й карте. Т.е. достают элемент дека из начала дека. Так происходит, пока колода одного из игроков не...

Непонятная ошибка (выход за границы вектора) - C++
Имеется следующий код // header.h #include &lt;windows.h&gt; #include &lt;vector&gt; ...

Не удаётся устранить необработанное исключение(выход за границы вектора) - C++
Помогите пожалуйста, по мне так всё правильно и аналогичная функция в другом месте работает, но всё равно выдает ошибку void...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru