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

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

Восстановить пароль Регистрация
 
HelicopterK52
633 / 176 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
21.08.2016, 15:40     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #1
Имеем код:
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, поэтому решение должно быть расширяемым без особого труда.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.08.2016, 15:40     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти
Посмотрите здесь:

C++ Правильное освобождение памяти
C++ Уничтожение указанных объектов
C++ Освобождение памяти из под Объектов в статическом массиве указателей
C++ Виртуальный деструктор и уничтожение объектов
C++ Освобождение памяти динамически созданных объектов
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
obivan
Падаван С++
 Аватар для obivan
172 / 158 / 41
Регистрация: 11.11.2014
Сообщений: 590
Завершенные тесты: 1
21.08.2016, 15:50     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #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");
}
HelicopterK52
633 / 176 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
21.08.2016, 15:51  [ТС]     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #3
obivan, +.
Но вот теги можно было бы поставить
obivan
Падаван С++
 Аватар для obivan
172 / 158 / 41
Регистрация: 11.11.2014
Сообщений: 590
Завершенные тесты: 1
21.08.2016, 15:52     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #4
HelicopterK52, забыл
HelicopterK52
633 / 176 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
21.08.2016, 15:59  [ТС]     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #5
Кликните здесь для просмотра всего текста
obivan, только у Вас функция release совсем бесполезная. В параметрах - копия указателя, так что reset ни на что не повлияет. Уничтожение будет происходить в конце каждой итерации цикла в main. В данном случае это не страшно, но всё же.
obivan
21.08.2016, 16:01
  #6

Не по теме:

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

Babysitter
 Аватар для Babysitter
78 / 103 / 34
Регистрация: 23.11.2015
Сообщений: 315
Завершенные тесты: 1
21.08.2016, 19:15     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #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);
    }
}
нужно зашаблонить еще
avgoor
562 / 352 / 83
Регистрация: 05.12.2015
Сообщений: 1,137
22.08.2016, 17:07     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #8
obivan, HelicopterK52, Вы сами-то этот код запускали? Как умный указатель сделает из невиртуального деструктора виртуальный?
obivan
Падаван С++
 Аватар для obivan
172 / 158 / 41
Регистрация: 11.11.2014
Сообщений: 590
Завершенные тесты: 1
22.08.2016, 17:20     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #9
avgoor, http://stackoverflow.com/questions/3...ared-ptr-magic

Добавлено через 13 секунд
запустите то код и проверьте
HelicopterK52
633 / 176 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
22.08.2016, 17:22  [ТС]     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #10
Цитата Сообщение от avgoor Посмотреть сообщение
Вы сами-то этот код запускали?
А Вы?
http://rextester.com/YCL74424
Цитата Сообщение от avgoor Посмотреть сообщение
Как умный указатель сделает из невиртуального деструктора виртуальный?
У shared_ptr под капотом некий "хелпер", который знает какой объект внутри, так что всё нормально будет.
То есть shared_ptr не сделает деструктор виртуальным, он лишь произведет правильное уничтожение объекта.
Можете поизучать соответствующую литературу, документацию.
Ferrari F1
Заблокирован
295 / 281 / 61
Регистрация: 27.01.2015
Сообщений: 1,889
Записей в блоге: 1
Завершенные тесты: 1
22.08.2016, 17:28     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #11
HelicopterK52, не осилил, лень читать такую тягомотину, старайся сделать задачку максимально сжатой по коду (10 строк максимум) и вообще по объему.

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

Не по теме:

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

HelicopterK52
22.08.2016, 17:34  [ТС]
  #14

Не по теме:

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

avgoor
562 / 352 / 83
Регистрация: 05.12.2015
Сообщений: 1,137
22.08.2016, 17:46     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #15
HelicopterK52, obivan, Тьфу, блин, ступил. Обычно unique_ptr возвращается, а я сейчас "выхожу из состояния глубокой отладки", вот и заклинило.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.08.2016, 17:49     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти
Еще ссылки по теме:

C++ Освобождение памяти для объектов производного класса
C++ Правильное освобождение памяти
Правильное освобождение памяти при std::vector C++

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

Или воспользуйтесь поиском по форуму:
HelicopterK52
633 / 176 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
22.08.2016, 17:49  [ТС]     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти #16
avgoor, да, с unique_ptr такое не прокатит
Yandex
Объявления
22.08.2016, 17:49     Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти
Ответ Создать тему
Опции темы

Текущее время: 00:08. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru