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

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

Войти
Регистрация
Восстановить пароль
 
Gr1f0nn
240 / 160 / 74
Регистрация: 30.09.2012
Сообщений: 685
#1

Ошибка при резервировании памяти для своего(!) вектора - C++

06.07.2015, 21:53. Просмотров 253. Ответов 11
Метки нет (Все метки)

Всем здравствуйте!
Возможно, из названия темы не совсем понятен вопрос, поэтому уточню саму суть:
Пишу свой шаблонный класс вектора и столкнулся со странной проблемой: при вызове функции reserve, которая, если верить описанию, должна увеличить емкость вектора, если текущая емкость меньше заданной, происходит ошибка времени компиляции (если я правильно классифицировал ошибку).
Вот сама функция:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template<class T>
void array<T>::reserve(std::size_t size)
{
    if(this->capacity_ < size)
    {
        array<T> buffer(*this);
        this->clear();
        this->array_ = new T[size];
        this->capacity_ = size;
        this->size_ = buffer.size_;
 
        for(std::size_t i = 0; i < this->size_; ++i)
        {
            (*this)[i] = buffer[i];
        }
        //buffer.clear();
        //delete[] buffer.array_;
// buffer.~array();
    }
}
Если закомментировать строку, которая должна освобождать память, выделенную для объекта buffer, то все работает корректно, однако если освободить ее вручную, то происходит эта ошибка.
Почему так? Правильно ли я понимаю, что компилятор сам освободит выделенную память локального объекта? И если я ее освобождаю вручную, то он пытается вызвать дестркутор этого объекта и освободить уже освобожденную память?
Однако, не противоречит ли это правилу: "выделил память - не забудь ее освободить"?

Собственно, дестркутор и функция clear, и конструктор копирования с операций присваивания:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    ~array() { this->clear(); }
    inline void clear() { delete[] this->array_; }
template<class T>
array<T>::array(const array<T> &copy)
{
    *this = copy;
}
template<class T>
array<T>::array(const iterator beg, const iterator end)
{
    std::size_t distance = int(end) - int(beg);
    this->array_ = new T[distance];
    this->size_ = distance;
    this->capacity_ = distance;
    for(std::size_t i = 0; i < distance; ++i)
        (*this)[i] = *(beg + i);
}
Заранее спасибо!
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.07.2015, 21:53
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ошибка при резервировании памяти для своего(!) вектора (C++):

Ошибка при использовании for_each для вектора - C++
Здравствуйте, форумчане,при компиляции возникает ошибка: c:\program files\microsoft visual studio 10.0\vc\include\algorithm(22): error...

Ошибка с итераторами для целочисленного вектора и вектора структуры - C++
Пытаюсь разобраться с векторами. Для динамической работы с памятью вещь, вроде, замечательная и удобная. Только необходимо использовать...

Ошибка при выделении памяти динамически для структуры - C++
Есть программа. Вылетает ошибка. Если gets(BLOCKNOTE.NAME) заменить на cin&gt;&gt;BLOCKNOTE.NAME все работает нормально. Хотелось бы ипользовать...

Динамическое выделение памяти для Вектора ( не STL) - C++
привет Ребят, Задание таково, прога читает слова из файла и в зависимости от выбора опций показывает мне количество уникальных слов,...

Создание своего вектора - C++
Мне пришлось юзать длинку, для перевода больших чисел в разных системах счисления, юзать СТЛ нельзя, вот и пришлось создавать клас, который...

Ошибка при сохранении вектора - C++
Привет всем! После сохранении в файл вектора (дин. масс.) и чтения его в другой вектор, вылазит отакая ошибка: собственно ошибка...

11
Max Dark
шКодер самоучка
1841 / 1641 / 598
Регистрация: 09.10.2013
Сообщений: 3,664
Записей в блоге: 6
Завершенные тесты: 2
06.07.2015, 22:02 #2
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Gr1f0nn, buffer - это локальная переменная и деструктор для нее вызовется автоматически при выходе из функции
1
Gr1f0nn
240 / 160 / 74
Регистрация: 30.09.2012
Сообщений: 685
06.07.2015, 22:06  [ТС] #3
Cra3y, Спасибо! Я-то думал, что всегда надо освобождать выделенную память, даже для локальных объектов. Буду знать теперь =)
0
Max Dark
шКодер самоучка
1841 / 1641 / 598
Регистрация: 09.10.2013
Сообщений: 3,664
Записей в блоге: 6
Завершенные тесты: 2
06.07.2015, 22:12 #4
Gr1f0nn, освобождать память надо для простых указателей(int* tmp = new int[sz];) используемых только в этой функции, а лучше использовать "умные указатели" - std::shared_ptr/std::unique_ptr (#include <memory>)
1
Gr1f0nn
240 / 160 / 74
Регистрация: 30.09.2012
Сообщений: 685
06.07.2015, 22:14  [ТС] #5
Cra3y, А разве в данном случае это не будет являться простым указателем?:
C++
1
2
3
4
5
6
7
8
9
10
template<class T>
class array
{
private:
    T* array_;
    std::size_t size_;
    std::size_t capacity_;
public:
....
};
Грубо говоря, в случае:
C++
1
2
3
4
5
6
7
8
int main()
{
    array<int> mass;
 
    for(int i = 0; i < 10; ++i)
        mass.push_back(rand()%10);
    return 0;
}
T ~ int и получается ситуация, когда int* array_ = new int[size];
0
Max Dark
шКодер самоучка
1841 / 1641 / 598
Регистрация: 09.10.2013
Сообщений: 3,664
Записей в блоге: 6
Завершенные тесты: 2
06.07.2015, 22:18 #6
Gr1f0nn, здесь по смыслу нужно освобождать в деструкторе, но деструктор опять же будет вызван автоматически
1
Gr1f0nn
240 / 160 / 74
Регистрация: 30.09.2012
Сообщений: 685
06.07.2015, 22:22  [ТС] #7
Cra3y, Так, теперь яснее стало.
Но возник вопрос: бывают ли случаи, когда нужно вызвать деструктор\ освободить память вручную?
Не беря во внимание связные списки, где (насколько мне известно), чтобы что-то удалить, нужно сделать это явно, вызвав оператор delete.
0
Max Dark
шКодер самоучка
1841 / 1641 / 598
Регистрация: 09.10.2013
Сообщений: 3,664
Записей в блоге: 6
Завершенные тесты: 2
06.07.2015, 22:41 #8
Gr1f0nn, я не могу придумать ситуации когда нужно вызывать деструктор в ручную.
0
DrOffset
7316 / 4416 / 1000
Регистрация: 30.01.2014
Сообщений: 7,253
06.07.2015, 22:48 #9
Цитата Сообщение от Gr1f0nn Посмотреть сообщение
Но возник вопрос: бывают ли случаи, когда нужно вызвать деструктор вручную?
Если объект был сконструирован через placement new.
Если объект c нетривиальными конструктором\деструктором находится внутри union (верно только в C++11).
1
Gr1f0nn
240 / 160 / 74
Регистрация: 30.09.2012
Сообщений: 685
06.07.2015, 22:54  [ТС] #10
Cra3y, Все, кажется я понял свою ошибку в понимании, когда нужно, а когда нет вызвать дестркутор\ освобождение памяти.
В данном случае, да и в других подобных, как Вы выше и написали, дестркутор будет вызван автоматически.

Добавлено через 4 минуты
DrOffset, вот про
Цитата Сообщение от DrOffset Посмотреть сообщение
placement new.
и
Цитата Сообщение от DrOffset Посмотреть сообщение
Если объект c нетривиальными конструктором\деструктором находится внутри union (верно только в C++11).
не знал совсем. Спасибо, буду знать теперь и это.
Сам такое еще не встречал и не реализовывал. Возможно, поэтому и образовался такой пробел в знаниях ^_^
0
DrOffset
7316 / 4416 / 1000
Регистрация: 30.01.2014
Сообщений: 7,253
06.07.2015, 22:59 #11
Цитата Сообщение от Gr1f0nn Посмотреть сообщение
не знал совсем.
Между тем у меня спасибка от тебя вот на это сообщение. А там как раз есть и placement new и ручной вызов деструктора.
0
Gr1f0nn
240 / 160 / 74
Регистрация: 30.09.2012
Сообщений: 685
06.07.2015, 23:09  [ТС] #12
DrOffset, Я и не знал, что это и есть тот случай

Не по теме:

тогда еще все, что касалось выделения памяти, а тем более того, как это реализовано в случае с вектором, для меня было совсем страшно и я, заглянув под спойлер, не много чего понял ^_^

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.07.2015, 23:09
Привет! Вот еще темы с ответами:

Ошибка при использовании вектора - C++
Пытаюсь проанализировать текстовый файл и посчитать кол-во каждого символа. Текст на английском. Вот код: class Raspredelenie{ ...

Ошибка при инициализации вектора списком - C++
В книге Страуструпа элементы вектора объявляются так vector&lt;int&gt; v = { 5 , 7 , 9 , 4 , 6 , 8 } ;В netbeans (linux ubuntu) ide выдаёт...

Ошибка при компиляции шаблонного вектора - C++
Написал вот такой код: #include &lt;cstring&gt; #include &lt;iostream&gt; #include &lt;cassert&gt; using namespace std; template &lt; class T &gt;...

Ошибка памяти при выполнении, при компиляции не выводит ошибки - C++
ПОмогите плс программа вводит строку символов до точки, а после вычисляет процент согласных в этой строке и выводит их в обратном порядке....


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

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

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