Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 37, средняя оценка - 4.68
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 12:39     Проверить на выход за границы массива #1
ПРивет, помогите пожалуйста, пишу класс - динамический массив, в перегрузке оператора [] нужно проверить на выход за границы, но не знаю как правильно использовать 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]; // и как быть тут куда вставить эту строку
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Кудаив
328 / 405 / 24
Регистрация: 27.05.2012
Сообщений: 1,162
Завершенные тесты: 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();
    }
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
05.05.2013, 12:51     Проверить на выход за границы массива #3
1) Ловить исключения - это забота клиентского кода. Поэтому просто бросайте out_of_range,
try и catch здесь не нужны. Только задекларируйте в документации класса или самого метода,
что он может бросать данное исключение, чтобы для клиента это не стало сюрпризом.

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

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

Не по теме:

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

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
Кудаив
328 / 405 / 24
Регистрация: 27.05.2012
Сообщений: 1,162
Завершенные тесты: 2
05.05.2013, 14:17     Проверить на выход за границы массива #6
Цитата Сообщение от Kreativ Посмотреть сообщение
1) Ловить исключения - это забота клиентского кода. Поэтому просто бросайте out_of_range,
try и catch здесь не нужны. Только задекларируйте в документации класса или самого метода,
что он может бросать данное исключение, чтобы для клиента это не стало сюрпризом.
это советы не для новичка, делай как тебе удобно
Убежденный
Системный программист
 Аватар для Убежденный
14191 / 6206 / 985
Регистрация: 02.05.2013
Сообщений: 10,339
Завершенные тесты: 1
05.05.2013, 14:21     Проверить на выход за границы массива #7
Цитата Сообщение от Kreativ Посмотреть сообщение
тогда придется в main'е делать try catch ? хотя можно написать функции в которых будут создаваться объекты и там уже try catch
Да. Выбор стратегии зависит от конкретных условий и сценариев использования класса.
Одни ошибки можно перехватить и обработать локально, после чего продолжить выполнение,
другие лучше не "прокидывать" и не маскировать, а выдать пользователю сообщение и
завершить работу программы.
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;
}
где мне обрабатывать искл. внутри перегруженного оператора или нет?
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
05.05.2013, 16:18     Проверить на выход за границы массива #9
Цитата Сообщение от Kreativ Посмотреть сообщение
где мне обрабатывать искл. внутри перегруженного оператора или нет?
нет
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;
чтобы не очищать память пустого массива
и как быть если скажем память не выделилась, тогда мой массив останется пустым, его размеры изменятся
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 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
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
05.05.2013, 16:39     Проверить на выход за границы массива #12
Сообщать об исключении и тем более гасить его - совершенно не операторское дело. Его задача только "подчистить" что возможно и насколько возможно в данной ситуации и передать исключение дальше. Таким образом, порядок действий такой:
а) выделить память под новый массив, исключение при этом перехватывать не надо: если возникнет ошибка, то сам объект пока что в прежнем состоянии и никакие ресурсы не утекли.
б) переписать содержимое копируемого объекта в выделенную память, перехватывая исключения. Если при копировании одного из элементов будет выброшено исключение, уже надо освобождать ресурсы: в обратном порядке уничтожить уже заполненные элементы нового массива и освободить сам массив.
в) уничтожить содержимое старого массива и освободить его, после чего заменить новым массивом. Эта операция не должна приводить к исключительным ситуациям (если тип T сделан по уму и его деструктор не выбрасывает исключений).
При таком порядке действий операция либо завершится успешно, либо будет прервана исключением, а сам объект при этом останется в том же состоянии, в котором был до начала операции (т.н. "сильная" гарантия безопасности). Утечек при возникновении исключений такой оператор тоже не создаст.
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 17:11  [ТС]     Проверить на выход за границы массива #13
Цитата Сообщение от Nick Alte Посмотреть сообщение
Если при копировании одного из элементов будет выброшено исключение, уже надо освобождать ресурсы: в обратном порядке уничтожить уже заполненные элементы нового массива и освободить сам массив.
затем в пункте В
Цитата Сообщение от Nick Alte Посмотреть сообщение
в) уничтожить содержимое старого массива и освободить его, после чего заменить новым массивом.
а так новый массив то пуст будет если будет выброшено исключение
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.05.2013, 17:15     Проверить на выход за границы массива #14
Третий пункт не выполняется, если во втором вылетает исключение.
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
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
05.05.2013, 18:33     Проверить на выход за границы массива #16
Не совсем хорошо то, что создаётся сразу инициализированный массив со значениями по умолчанию. По-хорошему надо бы выделить "сырую" память и создавать значения непосредственно из исходных данных. При текущем положении дел Array нельзя применять для типов, не имеющих конструктора по умолчанию. Далее, при выполнении 3 пункта наступает лютый трындец: зачем-то выделяется ещё один (!) массив, куда копируются данные из временного. Что за ерунда? Надо было просто написать aPtr = ptr;
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 19:07  [ТС]     Проверить на выход за границы массива #17
Цитата Сообщение от Nick Alte Посмотреть сообщение
Не совсем хорошо то, что создаётся сразу инициализированный массив со значениями по умолчанию.
вы имеете в виду, что в конструкторе по умолчанию создается сразу инициализированный массив?
я же здесь выделил "сырую" память и скопировал значения из массива:
C++
1
2
3
4
5
6
7
     T *ptr = new T[arrayForAssign.currentSize]; // выделил память
        size_t s = arrayForAssign.currentSize;
 
        try {      // 2 пункт
            for (size_t i = 0; i < arrayForAssign.currentSize; i++) {
                ptr[i] = arrayForAssign.aPtr[i];  скопировал во временный массив
            }
Цитата Сообщение от Nick Alte Посмотреть сообщение
при выполнении 3 пункта наступает лютый трындец: зачем-то выделяется ещё один (!) массив, куда копируются данные из временного. Что за ерунда? Надо было просто написать aPtr = ptr;
я не знаю с чего решил, что раз локальная переменная ptr, то и очистится память по заврешении оператора, моя оплошность
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.05.2013, 19:50     Проверить на выход за границы массива #18
Цитата Сообщение от Nick Alte Посмотреть сообщение
Не совсем хорошо то, что создаётся сразу инициализированный массив со значениями по умолчанию. По-хорошему надо бы выделить "сырую" память и создавать значения непосредственно из исходных данных.
О да, и писать свой scoped_partially_initialized_array!
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 19:54  [ТС]     Проверить на выход за границы массива #19
а что значит scoped_partially_initialized_array?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.05.2013, 20:02     Проверить на выход за границы массива
Еще ссылки по теме:

Пользователь вводит с клавиатуры две границы диапазона и число. Проверить, попадает ли число в диапазон C++
C++ При вызове функции необработанное исключение, выход за границы массива
Почему происходит выход за границы? C++

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

Или воспользуйтесь поиском по форуму:
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.05.2013, 20:02     Проверить на выход за границы массива #20
Это такой выдуманный класс, хранящий указатель на кусок памяти, который на самом деле является массивом, для которого частично вызваны конструкторы. И деструктор которого должен вызвать деструкторы для того, для чего вызывались ранее конструкторы, а потом освободить память того куска.
Yandex
Объявления
05.05.2013, 20:02     Проверить на выход за границы массива
Ответ Создать тему
Опции темы

Текущее время: 23:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru