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

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

24.06.2019, 14:29. Показов 1816. Ответов 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)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.06.2019, 14:29
Ответы с готовыми решениями:

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

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

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

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

Цитата Сообщение от Uncleewe Посмотреть сообщение
Shared_ptr чистит память и указатели из сета должны указывать в никуда. Где я не прав?
От того, что вы освободили память по заданному адресу, указатель в set не стал указывать в магическое "никуда". Он все так же указывает на ту же память, ведь адрес вы не меняли. Не меняли же? Не меняли.
Другое дело, что теперь память не принадлежит вам, и вы не можете ее легально использовать. Память отдана обратно менеджеру кучи.
1
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
24.06.2019, 14:52
Цитата Сообщение от Uncleewe Посмотреть сообщение
У меня же в сете указатели, а не объекты. Shared_ptr чистит память и указатели из сета должны указывать в никуда. Где я не прав?
Сделай unordered_set<std::weak_ptr<Base>>
0
1 / 1 / 0
Регистрация: 20.09.2017
Сообщений: 27
24.06.2019, 15:00  [ТС]
DrOffset, ну не в никуда я скорее не понял, почему там ещё что-то находится, если я вызвал деструктор. Не подумал, что ему удалять-то особо нечего. И как я понял, по этому адресу потом может оказаться что угодно, верно? Ну а если я сырой указатель удалю с помощью delete, то указатель же станет nullptr, почему тут не так?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
24.06.2019, 15:10
del
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.06.2019, 15:11
Лучший ответ Сообщение было отмечено 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
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
24.06.2019, 15:12
Цитата Сообщение от zayats80888 Посмотреть сообщение
а что изменится?
Увидит что объекты удалены. По-моему, это и требовалось
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.06.2019, 15:14
Цитата Сообщение от Uncleewe Посмотреть сообщение
И как я понял, по этому адресу потом может оказаться что угодно, верно?
Да, в том числе и старые данные. Но обращаться к ним нельзя. При таком обращении вся ваша программа входит в некорректное состояние и поведение ее предсказать уже нельзя.
1
1 / 1 / 0
Регистрация: 20.09.2017
Сообщений: 27
24.06.2019, 15:19  [ТС]
oleg-m1973, тогда придётся перегружать hash и equal. И я упростил код. Если у меня будет здесь weak_ptr, то придётся наследовать от enable_shared_from_this и это еще не все проблемы. Я бы хотел пока разобраться с более простыми вещами
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
24.06.2019, 15:23
Цитата Сообщение от Uncleewe Посмотреть сообщение
Если у меня будет здесь weak_ptr, то придётся наследовать от enable_shared_from_this.
Зачем? Наследоваться надо только если ты хочешь получать shared_ptr по ссылке на объект, иначе не нужно
0
1 / 1 / 0
Регистрация: 20.09.2017
Сообщений: 27
24.06.2019, 15:25  [ТС]
oleg-m1973, я же говорю, что упростил код. Мне и надо передавать this.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.06.2019, 15:25
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru