829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
1

Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти

21.08.2016, 15:40. Показов 816. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Имеем код:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
 
 
struct Base
{
public:
    ~Base() { std::cout << "Base::~Base" << std::endl; }
};
 
 
 
struct First : Base
{
public:
    ~First() { std::cout << "First::~First" << std::endl; }
};
 
 
 
 
struct Second : Base
{
public:
    ~Second() { std::cout << "Second::~Second" << std::endl; }
};
 
 
 
Base *make()
{
    unsigned x = 0;
    if(!(std::cin >> x))
    {
        return nullptr;
    }
    if(x&1)
        return new First();
    return new Second(); 
}
 
 
 
 
void release(Base *ptr)
{
    delete ptr;
}
 
 
 
 
int main()
{
    while(true)
    {
        auto ptr1 = make();
        if(ptr1 == nullptr)
        {
            break;
        }
        //...
        release(ptr1);
    }
}
make создает объекты в зависимости от ввода пользователя, при ошибке ввода возвращает nullptr.
Если ввод удался, то создается соответствующий объект (это может быть расширено в дальнейшем).
В данном коде деструкторы не виртуальные, поэтому в release будет вызван лишь деструктор базового класса.

Задача:
Поменять make и release таким образом, чтобы организовать правильное уничтожение объектов и освобождение памяти.

Учтите, что сами классы, а также функцию main менять нельзя. Также в будущем планируется добавлять наследников Base, поэтому решение должно быть расширяемым без особого труда.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.08.2016, 15:40
Ответы с готовыми решениями:

Правильное освобождение памяти
Здрасти. Двумерный динам. массив: int** matr=new int*; for (int i=0; i&lt;rows; ++i) matr=new int; ...

Правильное освобождение памяти
Есть код class Test { public: int **container; int counter = 0; Test(unsigned int size) { container = new int*;

Правильное освобождение памяти при std::vector
vector&lt;Worker*&gt; workers; workers.push_back(new Worker(&quot;Jack&quot;, 1000)) Как теперь правильно освободить память? Как я понял у...

15
Падаван С++
 Аватар для obivan
447 / 261 / 89
Регистрация: 11.11.2014
Сообщений: 916
21.08.2016, 15:50 2
HelicopterK52,
Кликните здесь для просмотра всего текста

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <memory>
struct Base
{
public:
    ~Base() { std::cout << "Base::~Base" << std::endl; }
};
 
struct First : Base
{
public:
    ~First() { std::cout << "First::~First" << std::endl; }
};
 
struct Second : Base
{
public:
    ~Second() { std::cout << "Second::~Second" << std::endl; }
};
 
std::shared_ptr<Base> make()
{
    unsigned x = 0;
    if (!(std::cin >> x))
    {
        return nullptr;
    }
    if (x & 1)
        return std::shared_ptr<Base>(new First());
    return std::shared_ptr<Base>(new Second());
}
 
 
 
 
void release(std::shared_ptr<Base> ptr)
{
    ptr.reset();
}
 
 
int main()
{
    int x = 0;
    while (x < 5)
    {
        auto ptr1 = make();
        if (ptr1 == nullptr)
        {
            break;
        }
        //...
        release(ptr1);
        x++;
    }
    system("pause");
}
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
21.08.2016, 15:51  [ТС] 3
obivan, +.
Но вот теги можно было бы поставить
0
Падаван С++
 Аватар для obivan
447 / 261 / 89
Регистрация: 11.11.2014
Сообщений: 916
21.08.2016, 15:52 4
HelicopterK52, забыл
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
21.08.2016, 15:59  [ТС] 5
Кликните здесь для просмотра всего текста
obivan, только у Вас функция release совсем бесполезная. В параметрах - копия указателя, так что reset ни на что не повлияет. Уничтожение будет происходить в конце каждой итерации цикла в main. В данном случае это не страшно, но всё же.
1
21.08.2016, 16:01 6

Не по теме:

HelicopterK52, а, точно, спасибо что заметили :)

0
 Аватар для Babysitter
245 / 139 / 53
Регистрация: 23.11.2015
Сообщений: 394
21.08.2016, 19:15 7
а я подумал про что-то такое и дооолго костылил
Кликните здесь для просмотра всего текста

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
 
struct Base
{
public:
    virtual void foo() {}
    ~Base() { std::cout << "Base::~Base" << std::endl; }
};
 
struct First : Base
{
public:
    void foo() override { std::cout << "First::foo" << std::endl; }
    ~First() { std::cout << "First::~First" << std::endl; }
};
 
struct Second : Base
{
public:
    void foo() override { std::cout << "Second::foo" << std::endl; }
    ~Second() { std::cout << "Second::~Second" << std::endl; }
};
 
// ugly
struct Wrapper
{
    enum class Type{ first, second };
    Wrapper(Base* base, Type type) : empty(false), type_(type), base_(base)  {}
    ~Wrapper() {
        switch(type_)
        {
            case Type::first:
                delete dynamic_cast<First*>(base_);
                break;
            case Type::second:
                delete dynamic_cast<Second*>(base_);
                break;
        }
    }
    // hack
    Wrapper(std::nullptr_t) : empty(true) {}
    bool operator==(std::nullptr_t) { return empty; }
    Base* operator->() { return base_; }
    Base& operator*() { return *base_; }
private:
    bool empty;
    Type type_;
    Base* base_;
};
bool operator==(std::nullptr_t, Wrapper& x) { return x == nullptr; }
 
Wrapper make()
{
    unsigned x = 0;
    if(!(std::cin >> x))
    {
        return nullptr;
    }
    if(x&1)
        return Wrapper{new First{}, Wrapper::Type::first};
    return Wrapper{new Second{}, Wrapper::Type::second}; 
}
 
void release(Wrapper&) {}
 
int main()
{
    while(true)
    {
        auto ptr1 = make();
        if(ptr1 == nullptr)
        {
            break;
        }
        ptr1->foo();
        release(ptr1);
    }
}
нужно зашаблонить еще
0
 Аватар для avgoor
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
22.08.2016, 17:07 8
obivan, HelicopterK52, Вы сами-то этот код запускали? Как умный указатель сделает из невиртуального деструктора виртуальный?
0
Падаван С++
 Аватар для obivan
447 / 261 / 89
Регистрация: 11.11.2014
Сообщений: 916
22.08.2016, 17:20 9
avgoor, http://stackoverflow.com/quest... -ptr-magic

Добавлено через 13 секунд
запустите то код и проверьте
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
22.08.2016, 17:22  [ТС] 10
Цитата Сообщение от avgoor Посмотреть сообщение
Вы сами-то этот код запускали?
А Вы?
http://rextester.com/YCL74424
Цитата Сообщение от avgoor Посмотреть сообщение
Как умный указатель сделает из невиртуального деструктора виртуальный?
У shared_ptr под капотом некий "хелпер", который знает какой объект внутри, так что всё нормально будет.
То есть shared_ptr не сделает деструктор виртуальным, он лишь произведет правильное уничтожение объекта.
Можете поизучать соответствующую литературу, документацию.
0
806 / 533 / 158
Регистрация: 27.01.2015
Сообщений: 3,017
Записей в блоге: 1
22.08.2016, 17:28 11
HelicopterK52, не осилил, лень читать такую тягомотину, старайся сделать задачку максимально сжатой по коду (10 строк максимум) и вообще по объему.

И тогда прочтение мною твоего поста обеспечено.
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
22.08.2016, 17:31  [ТС] 12
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
не осилил, лень читать такую тягомотину, старайся сделать задачку максимально сжатой по коду
Не осилил - не лезь.
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
И тогда прочтение мною твоего поста обеспечено.
Да мне как-то всё равно, прочитаешь ты его или нет. Надеюсь, я понятно выразился - ты не пуп земли. Так что учти это, когда следующий пост будешь писать. Как говорится, не указывайте мне что делать и...
0
22.08.2016, 17:34 13

Не по теме:

HelicopterK52, воу-воу, палехче, бро) Давай только без резкостей. Это сейчас нужно меньше всего :)
но читать, а уж тем более вникать в конце рабочего дня в длинный пост на самом деле не по кайфу

0
22.08.2016, 17:34  [ТС] 14

Не по теме:

Цитата Сообщение от Ferrari F1 Посмотреть сообщение
Давай только без резкостей. Это сейчас нужно меньше всего
:drink:

0
 Аватар для avgoor
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
22.08.2016, 17:46 15
HelicopterK52, obivan, Тьфу, блин, ступил. Обычно unique_ptr возвращается, а я сейчас "выхожу из состояния глубокой отладки", вот и заклинило.
0
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
22.08.2016, 17:49  [ТС] 16
avgoor, да, с unique_ptr такое не прокатит
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.08.2016, 17:49
Помогаю со студенческими работами здесь

Уничтожение объектов в инициализированной памяти. sed::allocator
Есть данный код: #include &quot;pch.h&quot; #include &lt;iostream&gt; #include &lt;memory&gt; using namespace std;

Освобождение памяти от объектов
Итак. Есть следующий код (элементы) type TStage = class(TObject) level: integer; Hero: THero; bullets:...

Освобождение памяти динамически созданных объектов
Подскажите, есть к примеру три класса: Class1, Class2, Class3. В Class2 имеется метод, в котором динамически создаю объекты класса...

Освобождение памяти для объектов производного класса
Всем привет. Не могу найти инфу в интернете, всё перерыл, но понял что случай специфичный у меня. Придумал себе конструкцию, но не уверен,...

Освобождение памяти из под Объектов в статическом массиве указателей
Всем добрый вечер! Решил расширить программу из книжки Лафорте Р. ООП в С++ стр. 574 путем добавления функции удаления данных о конкретном...


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

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

Редактор формул (кликните на картинку в правом углу, чтобы закрыть)
Опции темы

Новые блоги и статьи
Protobuf в Go и новый Opaque API
golander 15.03.2025
Распределенные системы опираются на эффективные протоколы обмена данными — о чем вы, скорее всего, прекрасно знаете, если работаете с микросервисной архитектурой. Protocol Buffers (Protobuf) от. . .
Преобразование строк в C++: std::from_chars от C++17 до C++26
NullReferenced 15.03.2025
Конвертация строк в числа — задача, с которой сталкивается практически каждый C++ разработчик. Несмотря на кажущуюся простоту, эта операция таит множество подводных камней и неочевидных последствий. . .
Управление памятью в Java и новые сборщики мусора
Javaican 15.03.2025
Эффективное управление памятью всегда было ахиллесовой пятой высоконагруженных Java-приложений. При разработке на Java мы обычно полагаемся на автоматическое управление памятью через сборщики мусора. . .
Angular или Svelte - что выбрать?
Reangularity 15.03.2025
Во фронтенд-разработке Angular и Svelte представляют собой два совершенно разных подхода к решению схожих задач. Один — полноценный, мощный монолит с корпоративной поддержкой, другой — компактный,. . .
Spring Cloud микросервисы: обнаружение и отслеживание
Javaican 15.03.2025
В разработке корпоративных приложений всё больше команд обращают внимание на микросервисную архитектуру. Но с этой архитектурой приходят и специфичные трудности: как сервисам находить друг друга в. . .
Запуск контейнера Docker в облаке
Mr. Docker 15.03.2025
Что такое Docker-контейнер? Если коротко — это легковесный, автономный пакет, содержащий всё необходимое для запуска приложения: код, зависимости, библиотеки и конфигурации. Когда мы говорим о. . .
Осваиваем Kubernetes: Подробная шпаргалка
Mr. Docker 15.03.2025
Kubernetes — это открытая платформа для автоматизации развертывания, масштабирования и управления контейнеризированными приложениями. Он был создан для решения проблем, с которыми сталкиваются. . .
Лучшие PHP REST API фреймворки
Jason-Webb 15.03.2025
Современные PHP REST API фреймворки предлагают большой набор функциональности: от автоматической валидации данных и управления маршрутизацией до генерации документации и интеграции с различными. . .
Многопоточность в Java с Project Loom: виртуальные или обычные потоки
Javaican 15.03.2025
Многопоточность всегда была одноим из основных элементов в разработке современного программного обеспечения. Она позволяет приложениям обрабатывать несколько задач одновременно, что критично для. . .
Что нового в Swift 6 и особенности миграции
mobDevWorks 15.03.2025
Swift 6 — это новый крупный релиз языка программирования от Apple, анонсированный на WWDC 2024. Если вы следили за эволюцией Swift, то наверняка заметили, что многие значимые возможности, которые. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru