Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

использование operator[]

445
19 августа 2011 года
Charley
176 / / 16.08.2011
Возникает ошибка "bad_alloc по адресу..." при использование operator[]. Отладчик показывает на строку Element *link = new Element; в методе push класса list. Оператор находится в классе Array и нужен для выделении новой памяти при заполнении старого массива.
Код:
class Array {
    public:
    list* H;
    list* temp;
    long MaxCount;
    Array() {
        MaxCount=10;
        H = new list[MaxCount];
    }
    list& operator[] (int index) {
        if (index==MaxCount) {
            temp=H;
            //delete[] H;
            MaxCount+=3000;
            H = new list[MaxCount];
            H=temp;
        }
    return H[index];
    }
};
278
19 августа 2011 года
Alexander92
1.1K / / 04.08.2008
Цитата: Charley

 
Код:
temp=H;
    //...
    H=temp;


Ну так что ж вы делаете? Вы ведь, по сути, возвращаете указатель на старое место, а нововыделенная память просто теряется. Вам нужно запомнить старое содержимое H (не указатель на него, а сам список), потом выделить память, а потом скопировать в начало новой памяти то, что вы запомнили раньше.

Еще момент: цифра 3000, я так понимаю, взялась от фонаря. Вам нужно гарантировать, что при _любых_ обстоятельствах (даже если вы напишете arrayInstance[100000]) вы не выйдете за границу диапазона. Иначе теряется смысл того, что вы делаете.

445
20 августа 2011 года
Charley
176 / / 16.08.2011
Цитата: Alexander92
Ну так что ж вы делаете? Вы ведь, по сути, возвращаете указатель на старое место, а нововыделенная память просто теряется. Вам нужно запомнить старое содержимое H (не указатель на него, а сам список), потом выделить память, а потом скопировать в начало новой памяти то, что вы запомнили раньше.



Давай проанализируем, что нужно сделать, чтобы сделать так как сказал ты. Если я где-то не прав, можешь меня поправить.
Порядок действий:
1. Выделить память для резервного храненения содержимого списка(запасной список).
2. Скопировать содержимое из старого списка в запасной список.
3. Выделить память большего размера для нового списка.
4. Скопировать из старого(резервного) списка в новый.
Перечисляю все это даже без операций delete[]. Повторю вопрос: целесообразно ли по времени так делать или проще выделить сразу ОЧЕНЬ МНОГО памяти?

277
20 августа 2011 года
arrjj
1.7K / / 26.01.2011
Цитата: Charley
Давай проанализируем, что нужно сделать, чтобы сделать так как сказал ты. Если я где-то не прав, можешь меня поправить.
Порядок действий:
1. Выделить память для резервного храненения содержимого списка(запасной список).
2. Скопировать содержимое из старого списка в запасной список.
3. Выделить память большего размера для нового списка.
4. Скопировать из старого(резервного) списка в новый.
Перечисляю все это даже без операций delete[]. Повторю вопрос: целесообразно ли по времени так делать или проще выделить сразу ОЧЕНЬ МНОГО памяти?



Неправильно.
1. Выделить память большего размера под новый список с указателем temp
2. Скопировать содержимое старого списка в новый (а не указатель как у тебя в примере) (memcpy например из указателя H в указатель temp)
3. Удалить старый список (указатель H)
4. Присвоить указателю H новое значение (H=temp)
Основной минус такого подхода: при выделении памяти большего размера старая ещё используется, поэтому необходимо в 2 раза больше памяти свободной.
Варианты решения:
1. Использовать готовые классы списков (из тогоже stl например) и не париться по этому поводу.
2. Сделать массив указателей списков list**, с фиксированным количеством элементов, так при обращении к элементу N возвращаем референс на list[N/фиксированное_число][N%фиксированное_число]

Ну и ещё один недочёт в твоём примере - ты выделяешь доп. память только при обращении к первому элементу за границами массива, а если обратиться к например 10-му (list[MaxCount+9]) у тебя вернёт полную хрень и не выделит память.

278
20 августа 2011 года
Alexander92
1.1K / / 04.08.2008
Цитата: Charley
Перечисляю все это даже без операций delete[]. Повторю вопрос: целесообразно ли по времени так делать или проще выделить сразу ОЧЕНЬ МНОГО памяти?


Целесообразнее всего при каждом выходе за границы диапазона выделять настолько много новой памяти, чтобы в следующий раз выйти за границы не скоро. Конечно, проще действительно выделить сразу "ОЧЕНЬ МНОГО", но это некрасивое решение.

297
20 августа 2011 года
koodeer
1.2K / / 02.05.2009
Чтобы не мучиться с вопросом, сразу выделить много памяти или потом выделять, нужно оставить это на откуп пользователю класса: предусмотреть задание размера буфера в конструкторе класса.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог