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

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

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

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

05.05.2013, 12:39. Просмотров 5453. Ответов 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]; // и как быть тут куда вставить эту строку
}
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; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Nick Alte
Эксперт С++
1636 / 1008 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 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
~ Эврика! ~
1243 / 992 / 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?
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.05.2013, 20:02 #20
Это такой выдуманный класс, хранящий указатель на кусок памяти, который на самом деле является массивом, для которого частично вызваны конструкторы. И деструктор которого должен вызвать деструкторы для того, для чего вызывались ранее конструкторы, а потом освободить память того куска.
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 20:20  [ТС] #21
задание просто такое, получил такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 = ptr;
            return *this;
        }
        catch(...) {
            delete [] ptr;   
        }  
    }
    return *this;
}
все ли правильно?
я не понял только где у меня
Цитата Сообщение от Nick Alte Посмотреть сообщение
создаётся сразу инициализированный массив со значениями по умолчанию.
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
05.05.2013, 20:23 #22
Цитата Сообщение от Kreativ Посмотреть сообщение
я не понял только где у меня
строка 4
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 20:27  [ТС] #23
я же просто выделил память и ничего больше
Somebody
2788 / 1602 / 145
Регистрация: 03.12.2007
Сообщений: 4,193
Завершенные тесты: 1
05.05.2013, 20:28 #24
Так new для каждого элемента вызывает конструктор по умолчанию (для классов).
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 20:29  [ТС] #25
точно, подскажите тогда как мне переделать
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.05.2013, 21:40 #26
Цитата Сообщение от Kreativ Посмотреть сообщение
точно, подскажите тогда как мне переделать
Никак. Забейте. Вам это не нужно.

Как сделать exception-safe копирование динамического массива без вызова конструкторов по умолчанию я уже говорил: специальный хитровыедуманным классом. Там строк на 50 кода.
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
05.05.2013, 21:54  [ТС] #27
это про scoped_partially_initialized_array ?
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.05.2013, 22:02 #28
Ага. У него:
  • конструктор, принимающий количество будущих элементов массива и выделяющий кусок сырой памяти;
  • метод init(const T&), инициализирующий следующий элемент;
  • метод get() отдающий готовый кусок памяти с инициализированными элементами;
  • деструктор, дёргающий деструкторы для всего, что было инициализировано, и освобождающий сырую память (всё это при условии, что метод get() ранее не был вызван).
Примитивные выделяторы памяти зовутся void* operator new[](size_t n) и void operator delete[](void *). Первый принимает количество байт и возвращает кусок, второй принимает кусок и освобождает его. Для ручного вызова конструкторов копирования гуглите placement new. Как вызвать деструктор, думаю, догадаетесь.
Kreativ
2 / 2 / 0
Регистрация: 22.09.2012
Сообщений: 202
06.05.2013, 00:05  [ТС] #29
большое спасибо, сейчас начну делать

Добавлено через 2 часа 0 минут
я пишу класс по пунктам, которые вы перечислили, но кажется я не понял всю логику.
в метод init я буду отправлять по одному элементу, который нужно скопировать, в этом методе будет происходить инициализация внутреннего указателя класса, я так понял, что здесь нужно вызывать констр. копирования вручную?
после того как все элементы будут отправлены в метод init, методом get я должен буду получить все скопированные значения(из внутр. указ.)?
еще нужно будет перегрузить операторы new, delete и в конструкторе память выделять как обычно
p = new T[size];
а где и когда вызывать вручную деструкторы?
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
06.05.2013, 00:41 #30
Вот что за петух вас клюнул? У вас не продакшн-левел библиотека массивов, подобные извращения тут ни к чему.

Эта штука нужна для exception-safety при копировании массива. Её задача: или выдать вам в конце концов указатель на массив из корректно скопированных элементов, или аккуратно удалить весь мусор в случае выброса исключения в процессе копирования. Любого исключения, будь-то память не выделилась или конструктор копирования облажался.

Если бы вам кое-кто не подкинул мысль, что конструктор по умолчанию может и не существовать, то достаточно было бы примитивного варианта в три строки со временным массивом.

Перегружать ничего не надо. Это именно что такие функции, которые именно так и вызываются:
C++
1
2
3
T *ptr = reinterpret_cast<T*>(operator new[](N * sizeof(*ptr)));
///
operator delete[](ptr);
malloc() и free(), считайте.

Конструктор копирования с помощью placement new вызвается в том init().

get() возвращает тот указатель на массив, что вернул operator new[](), и в котором проводил инициализацию init(). После этого данный объект забывает этот указатель. Он передал ему тому, кто вызвал get().

Деструкторы вызываются в деструкторе этого класса. Вызывать их надо только для того, что было проинициализировано (надо помнить, какой кусок массива был проинициализирован, а какой — нет). И только в том случае, если get() не был вызван до этого.

Ещё раз говорю: забейте. Если вы не знаете, зачем это надо, то оно вам не надо. YAGNI.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.05.2013, 00:41
Привет! Вот еще темы с ответами:

Выход за границы. как исправить??? - 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...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
06.05.2013, 00:41
Ответ Создать тему
Опции темы

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