Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
1 / 1 / 0
Регистрация: 20.09.2017
Сообщений: 27
1

Утечка при комбинации сырого и умного указателя

24.06.2019, 14:29. Показов 1299. Ответов 12
Метки нет (Все метки)

После выхода из блока shared_ptr вызывает деструкторы объектов, но они почему-то остаются в unordered_set и последний for их успешно разыменовывает.

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
#include <bits/stdc++.h>
using namespace std;
 
class Base {
  public:
    Base(int x) : _x(x) {};
    virtual ~Base() {
      cout << "dead" << endl;
    }
 
    void X(int x) {
      _x = x;
    }
    int X() const { return _x; }
 
  private:
    int _x;
};
 
int main() {
  freopen("output.txt", "w", stdout);
  
  unordered_set<Base *> s;
  {
    shared_ptr<Base> x(new Base(10));
    shared_ptr<Base> y(new Base(12));
 
 
    s.insert(x.get());
    s.insert(y.get());
  }
 
  for (auto i : s)
    if (i != nullptr)
      cout << i->X() << endl;
    else 
      cout << "nullptr" << endl;
 
 
  return 0;
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.06.2019, 14:29
Ответы с готовыми решениями:

Реализация умного указателя
Добрый вечер. Сегодня с умным указателем поиграться. Написал обгортку : #pragma once template...

Доступ к полю умного указателя
Привет. Реализовал умный указатель. Появилась проблема: Если обращаться через перегруженный...

Проверить правильность реализации умного указателя
? template&lt;class T&gt; class Auto_Ptr { public: Auto_Ptr(); explicit Auto_Ptr(T* alloc);...

Использование умного указателя std::weak_ptr
Есть вот такой код иерархии классов. Нужно в последнем классе list, вместо динамического массива...

12
15350 / 8298 / 2014
Регистрация: 30.01.2014
Сообщений: 14,169
24.06.2019, 14:37 2
Uncleewe, шутить изволите? Откуда ж сету знать, что вы объект уничтожили?
0
1 / 1 / 0
Регистрация: 20.09.2017
Сообщений: 27
24.06.2019, 14:45  [ТС] 3
У меня же в сете указатели, а не объекты. Shared_ptr чистит память и указатели из сета должны указывать в никуда. Где я не прав?
0
15350 / 8298 / 2014
Регистрация: 30.01.2014
Сообщений: 14,169
24.06.2019, 14:51 4
Цитата Сообщение от Uncleewe Посмотреть сообщение
У меня же в сете указатели, а не объекты.
Опять наделяем указатели какой-то выдуманной магией? Указатель это тоже объект, который хранит адрес.

Цитата Сообщение от Uncleewe Посмотреть сообщение
Shared_ptr чистит память и указатели из сета должны указывать в никуда. Где я не прав?
От того, что вы освободили память по заданному адресу, указатель в set не стал указывать в магическое "никуда". Он все так же указывает на ту же память, ведь адрес вы не меняли. Не меняли же? Не меняли.
Другое дело, что теперь память не принадлежит вам, и вы не можете ее легально использовать. Память отдана обратно менеджеру кучи.
1
6745 / 4540 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
Записей в блоге: 1
24.06.2019, 14:52 5
Цитата Сообщение от Uncleewe Посмотреть сообщение
У меня же в сете указатели, а не объекты. Shared_ptr чистит память и указатели из сета должны указывать в никуда. Где я не прав?
Сделай unordered_set<std::weak_ptr<Base>>
0
1 / 1 / 0
Регистрация: 20.09.2017
Сообщений: 27
24.06.2019, 15:00  [ТС] 6
DrOffset, ну не в никуда я скорее не понял, почему там ещё что-то находится, если я вызвал деструктор. Не подумал, что ему удалять-то особо нечего. И как я понял, по этому адресу потом может оказаться что угодно, верно? Ну а если я сырой указатель удалю с помощью delete, то указатель же станет nullptr, почему тут не так?
0
4684 / 2513 / 1044
Регистрация: 07.02.2019
Сообщений: 6,545
24.06.2019, 15:10 7
del
0
15350 / 8298 / 2014
Регистрация: 30.01.2014
Сообщений: 14,169
24.06.2019, 15:11 8
Лучший ответ Сообщение было отмечено Uncleewe как решение

Решение

Цитата Сообщение от Uncleewe Посмотреть сообщение
далю с помощью delete, то указатель же станет nullptr, почему тут не так?
Не станет он nullptr. С чего вы взяли?

Да даже если бы и стал. Допустим мы сами напишем такой delete:
C++
1
2
3
4
5
6
template <typename T>
void smart_delete(T * & p)
{
    delete p;
    p = nullptr;
}
Вот у нас есть указатель
C++
1
int * p = new int(10);
потом мы поместили его копию в сет:
C++
1
s.insert(p);
потом мы используем наш умный delete на p
C++
1
smart_delete(p);
p после этого nullptr, но копия в set-то с какого перепугу должна обнуляться? Это другой объект.

Вот вам абсолютно аналогичный пример:
C++
1
2
3
int a = 1;
s.insert(a); // s - это unordered_set<int>
a = 2;
По вашей логике, получается, что элемент сета тоже должен стать равным 2.
0
6745 / 4540 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
Записей в блоге: 1
24.06.2019, 15:12 9
Цитата Сообщение от zayats80888 Посмотреть сообщение
а что изменится?
Увидит что объекты удалены. По-моему, это и требовалось
0
15350 / 8298 / 2014
Регистрация: 30.01.2014
Сообщений: 14,169
24.06.2019, 15:14 10
Цитата Сообщение от Uncleewe Посмотреть сообщение
И как я понял, по этому адресу потом может оказаться что угодно, верно?
Да, в том числе и старые данные. Но обращаться к ним нельзя. При таком обращении вся ваша программа входит в некорректное состояние и поведение ее предсказать уже нельзя.
1
1 / 1 / 0
Регистрация: 20.09.2017
Сообщений: 27
24.06.2019, 15:19  [ТС] 11
oleg-m1973, тогда придётся перегружать hash и equal. И я упростил код. Если у меня будет здесь weak_ptr, то придётся наследовать от enable_shared_from_this и это еще не все проблемы. Я бы хотел пока разобраться с более простыми вещами
0
6745 / 4540 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
Записей в блоге: 1
24.06.2019, 15:23 12
Цитата Сообщение от Uncleewe Посмотреть сообщение
Если у меня будет здесь weak_ptr, то придётся наследовать от enable_shared_from_this.
Зачем? Наследоваться надо только если ты хочешь получать shared_ptr по ссылке на объект, иначе не нужно
0
1 / 1 / 0
Регистрация: 20.09.2017
Сообщений: 27
24.06.2019, 15:25  [ТС] 13
oleg-m1973, я же говорю, что упростил код. Мне и надо передавать this.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.06.2019, 15:25

Ошибка умного указателя для формы
Приветствую. В хедере главной форме объявляю умный указатель на вторую форму: private: // User...

Не выводится сообшения от деструктора для умного указателя
#ifndef Shared_ptr_H #define Shared_ptr_H template&lt;class T&gt; class shared_ptr { private: ...

Написать шаблон умного указателя для массива
Добрый день уважаемые! Не могу решить 2 задачи! 1. У вас есть многосвязный список‚ заданный...

Как привести тип умного указателя к указателю на void?
Изучаем WinAPI, необходимо выполнить задание: Написать программу, которая в одном потоке сохраняет...


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

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

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