5 / 5 / 4
Регистрация: 18.11.2014
Сообщений: 81
1

Деструктор класса. Удаление динамически выделенного массива в классе

17.05.2015, 22:46. Показов 7166. Ответов 21
Метки нет (Все метки)

First.h
C++
1
2
3
4
5
6
7
8
9
class First
{
private:
    int* num;
    int n;
public:
    First(int a);
    ~First();
};
First.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "First.h"
 
First::First(int a)
{
    n = a;
    num = new int[a];
}
 
First::~First()
{
    delete[n] num;
}
Миниатюры
Деструктор класса. Удаление динамически выделенного массива в классе  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.05.2015, 22:46
Ответы с готовыми решениями:

Удаление динамически созданных объектов собственного класса
Подскажите пожалуйста, у меня есть два класса, член одного - динамический массив элементов другого...

Удаление динамического массива в классе
при удаление динамического массива в классе зависает программа... хотя в инете нашел кучу примеров,...

Деструктор в классе
Нужно создать класс бинарного дерева. Все сделано, кроме деструктора. Подскажите как с ним быть...

Конструктор и деструктор в классе
Решил разобраться в конструкторах и деструкторах. Написал, вроде по такой же структуре как и в...

21
lss
940 / 868 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
17.05.2015, 22:48 2
C++
1
delete [] num;
0
5 / 5 / 4
Регистрация: 18.11.2014
Сообщений: 81
17.05.2015, 23:05  [ТС] 3
ошибка
Миниатюры
Деструктор класса. Удаление динамически выделенного массива в классе  
0
lss
940 / 868 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
17.05.2015, 23:10 4
Цитата Сообщение от Fasterbru Посмотреть сообщение
ошибка
И что? Ошибка может быть из-за того, что где-то в коде память портится. При освобождении это проявляется.
0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
17.05.2015, 23:12 5
один из возможных вариантов: двойное удаление из-за отсутствия правильных конструкторов копирования и оператора =.
вот еще полезная тема: https://www.cyberforum.ru/cpp-... 62479.html
0
21 / 21 / 19
Регистрация: 18.03.2014
Сообщений: 148
17.05.2015, 23:15 6
Fasterbru,

Не по теме:

еще неплохо бы после выделения памяти добавить проверку. Не всегда операция "new" выделяет память. Бывают ситуации, когда она записывает в указатель NULL.

C++
1
2
3
4
5
num = new int[a];
if (!num) 
{ 
//обработать ошибку
}

0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
17.05.2015, 23:17 7
нули возвращаются разве что в особых режимах сборки при особой конфигурации. в стандарте в таких случаях бросаются исключения. если вы проверяете на nullptr после new, то больше так не делайте.
0
5 / 5 / 4
Регистрация: 18.11.2014
Сообщений: 81
17.05.2015, 23:20  [ТС] 8
Perfilov, lss, bogdan_017,
main.cpp
C++
1
2
3
4
5
6
7
8
9
10
#include "First.h"
 
 
int main()
{
    First perem(10);
    perem.~First();
 
    system("pause");
}
не использую конструктор копирования. ничего не делаю. проверку написал. память выделяется.
0
lss
940 / 868 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
17.05.2015, 23:23 9
Цитата Сообщение от bogdan_017 Посмотреть сообщение
num = new int[a];
if (!num)
{
//обработать ошибку
}
Тогда уж так:
C++
1
2
3
4
num = new (nothrow) int[a];
if (!num) 
{ 
//обработать ошибку
0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
17.05.2015, 23:25 10
не используете, однако delete вызывается дважды для одного и того же, что есть ошибка. первый раз при явном вызове деструктора (зачем???), второй - при автоматическом вызове деструктора.
0
Эксперт С++
8720 / 4300 / 958
Регистрация: 15.11.2014
Сообщений: 9,744
17.05.2015, 23:25 11
1 ошибка:

заменить
C++
1
delete[n] num;
на
C++
1
delete[] num;
2 ошибка.

конструктор копии и оператор присваивания должны быть либо определены,
либо явным образом запрещены.

в данном случае они не определены явно и не запрещены явно.

это значит поведение по дефолту.

это значит - если один объект будет создан как копия другого,
то имеем краш в деструкторе при уничтожении последнего объекта.
1
5 / 5 / 4
Регистрация: 18.11.2014
Сообщений: 81
17.05.2015, 23:26  [ТС] 12
lss, он проходит это нормально. я могу использовать эту память.
0
lss
940 / 868 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
17.05.2015, 23:26 13
Цитата Сообщение от Fasterbru Посмотреть сообщение
perem.~First();
Это UB.
0
5 / 5 / 4
Регистрация: 18.11.2014
Сообщений: 81
17.05.2015, 23:27  [ТС] 14
hoggy, 1 ошибку исправил. 2) я выше выложил код cpp где использую объект. там только создание и вызов деструктора.
0
lss
940 / 868 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
17.05.2015, 23:28 15
Не нужно здесь явно вызывать деструктор.
0
Эксперт С++
8720 / 4300 / 958
Регистрация: 15.11.2014
Сообщений: 9,744
17.05.2015, 23:29 16
Лучший ответ Сообщение было отмечено Fasterbru как решение

Решение

Цитата Сообщение от Fasterbru Посмотреть сообщение
nt main()
{
* * First perem(10);
* * perem.~First();
system("pause");
}
ну это жесть вообще.
для настоящих ценителей.

лекарство:

заменить:

C++
1
2
3
4
First::~First()
{
    delete[n] num;
}
на:

C++
1
2
3
4
5
First::~First()
{
    delete[n] num;
    num = nullptr;
}
правда за такое лекарство убивать нужно.
потому что UB, а значит никаких гарантий.
скорее всего работать будет.
но теоретически бабахнуть может в любой момент.

настоящее лекарство - престрелить нафиг того программиста,
который столь необдуманно в ручную дергает деструктор.
1
5 / 5 / 4
Регистрация: 18.11.2014
Сообщений: 81
17.05.2015, 23:29  [ТС] 17
lss, почему?
0
lss
940 / 868 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
17.05.2015, 23:30 18
Лучший ответ Сообщение было отмечено Fasterbru как решение

Решение

Если хочешь проверить работу деструктора, помести создание объекта в {}, тогда при выходе из этой области сработает деструктор.
1
Эксперт С++
8720 / 4300 / 958
Регистрация: 15.11.2014
Сообщений: 9,744
17.05.2015, 23:31 19
Цитата Сообщение от lss Посмотреть сообщение
Это UB.
это не UB.


более того - деструктор можно звать руками не просто так.
у этого есть применение.
целые иодемы и техники программирования доступны лишь благодаря такой возможности.

(см boost::optional, например)


А UB это:

C++
1
2
    {First perem(10);
    perem.~First(); }
0
lss
940 / 868 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
17.05.2015, 23:36 20
Цитата Сообщение от Fasterbru Посмотреть сообщение
lss, почему?
Потому, что он второй раз вызовется при выходе из программы (когда будет уничтожаться объект), а память уже освобождена.

Добавлено через 43 секунды
Цитата Сообщение от hoggy Посмотреть сообщение
более того - деструктор можно звать руками не просто так.
Написал:
Цитата Сообщение от lss Посмотреть сообщение
Не нужно здесь
Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
на:
C++
1
2
3
4
5
First::~First()
{
* * delete[n] num;
* * num = nullptr;
}
Это как? Что освобождаем?

Добавлено через 2 минуты
Цитата Сообщение от hoggy Посмотреть сообщение
А UB это:

C++
1
2
* * {First perem(10);
* * perem.~First(); }
А в коде у ТС разве не так? Скобки можно раздвинуть до границ main().
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.05.2015, 23:36
Помогаю со студенческими работами здесь

Ругается на деструктор (выделял динамически память). Почему?
Вот код: #include <stdio.h> #include <conio.h> #include <time.h> #include <stdlib.h> class...

Как динамически создать массив из динамически конструируемых экземпляров класса?
Есть два класса.Подразумевается ,что первый в конструкторе выделяет интовый массив длинной n,второй...

При динамическом создании объекта в классе деструктор не вызывается
Добрый день еще раз. Помогите заполнить пробелы в ООП) Есть три класса: // Вспомогательный класс...

Как использовать объект класса, созданого в определеном классе, в другом классе
У меня такой вопрос,как использовать объект класса,созданого в определеном классе,в другом классе.У...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru