powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пул на базе unique_ptr
25 сообщений из 63, страница 1 из 3
Пул на базе unique_ptr
    #39741519
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте эксперты

Задача - написать свой умный указатель - наследник std::unique_ptr с тем чтоб можно было
при освобождении памяти не удалять, а возвращать ее в пул.

Все работает - однако не получается положить pool_ptr в std::vector - какая та ругань на конструкторы перемещения.

Подскажите плиз - как это правильно делается.

Код: plaintext
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.
#include <inttypes.h>
#include <algorithm>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>

struct t {
 public:
  int v;

  ~t() { std::cout << "t->  destructor call" << std::endl; }
};

template <class _Tp, class _Dp = std::default_delete<_Tp>>
class pool_ptr : public std::unique_ptr<_Tp, _Dp> {
 public:
  ~pool_ptr() { this->release(); }
};

std::vector<pool_ptr<t>>* pool;

pool_ptr<t>& getPtr() { return pool->at(0); }

int main() {
  pool = new std::vector<pool_ptr<t>>();
  pool->emplace_back(new pool_ptr<t>());
  getPtr().reset(new t());
  getPtr().get()->v = 10001;
  std::cout << getPtr().get()->v << std::endl;
}




note: copy constructor is implicitly deleted because 'unique_ptr<t, std::__1::default_delete<t> >' has a user-declared move constructor
unique_ptr(unique_ptr&& __u) noexcept
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741521
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
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.
#include <inttypes.h>
#include <algorithm>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>

struct t {
 public:
  int v;

  ~t() { std::cout << "t->  destructor call" << std::endl; }
};

template <class _Tp, class _Dp = std::default_delete<_Tp>>
class pool_ptr : public std::unique_ptr<_Tp, _Dp> {
 public:
  ~pool_ptr() { this->release(); }
};

std::vector<pool_ptr<t>>* pool;

pool_ptr<t>& getPtr() { return pool->at(0); }

int main() {
  pool = new std::vector<pool_ptr<t>>();
  pool_ptr<t> ptr{};
  pool->emplace_back(std::move(ptr));
  getPtr().reset(new t());
  getPtr().get()->v = 10001;
  std::cout << getPtr().get()->v << std::endl;
}



error: call to implicitly-deleted copy constructor of 'pool_ptr<t, std::__1::default_delete<t> >' ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);


in instantiation of function template specialization 'std::__1::vector<pool_ptr<t, std::__1::default_delete<t> >, std::__1::allocator<pool_ptr<t, std::__1::default_delete<t> > > >::emplace_back<pool_ptr<t, std::__1::default_delete<t> > >' requested here
pool->emplace_back(std::move(ptr));
^

note: copy constructor of 'pool_ptr<t, std::__1::default_delete<t> >' is implicitly deleted because base class 'std::unique_ptr<t, default_delete<t> >' has a deleted copy constructor
class pool_ptr : public std::unique_ptr<_Tp, _Dp> {
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741534
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenЗадача - написать свой умный указатель - наследник std::unique_ptr с тем чтоб можно было
при освобождении памяти не удалять, а возвращать ее в пул.

Для этого не надо писать наследника, достаточно скормить обычному unique_ptr свой аллокатор.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741536
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovsemen.s.semenЗадача - написать свой умный указатель - наследник std::unique_ptr с тем чтоб можно было
при освобождении памяти не удалять, а возвращать ее в пул.

Для этого не надо писать наследника, достаточно скормить обычному unique_ptr свой аллокатор.


Я знаю

Но я вношу изменения в большой проект в котором на простом unique_ptr уже понаписана уйма кода

и менять в шаблоне аллокатор - адовый геморой

Вот решил просто отнаследоваться и переопределить деструктор
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741537
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenВот решил просто отнаследоваться и переопределить деструктор

Тогда переопределяй не деструктор, а оператор delete у класса, который пулится.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741538
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovsemen.s.semenВот решил просто отнаследоваться и переопределить деструктор

Тогда переопределяй не деструктор, а оператор delete у класса, который пулится.


А можно поподробнее ? Никогда этого не делал
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741547
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
struct  t {
   public:
    int  v;

    ~t() { std::cout <<"t-> destructor call"  << std::endl; }
    void* operator new(size_t size) { return pool.pop(); }
    void operator delete(void *ptr) { pool.push(ptr); }
};



Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741548
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
struct  t {
   public:
    int  v;

    ~t() { std::cout <<"t-> destructor call"  << std::endl; }
    void* operator new(size_t size) { return pool.pop(); }
    void operator delete(void *ptr) { pool.push(ptr); }
};





А если пулится char[] ?

И глобально для него делать оператор delete не вариант ?
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741559
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot semen.s.semen]Здравствуйте эксперты

Задача - написать свой умный указатель - наследник std::unique_ptr с тем чтоб можно было
при освобождении памяти не удалять, а возвращать ее в пул.

Все работает - однако не получается положить pool_ptr в std::vector - какая та ругань на конструкторы перемещения.

Вроде бы для этого не нужен совсем наследник unique_ptr.
unique_ptr сохраняет так называемый делитор, который будет вызван для удаления памяти.
По умолчанию это вызов delete или delete [] в зависимости от типа созданного объекта,
но там может быть любая функция.

Соответственно остаётся только задать эту функцию, а в ней не удалять объект, а помещать в пул памяти.
тАкже надо будет определить operator new, чтобы брать память из пула
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741561
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Повторю

1) Делетор подменить не получится

unique_ptr  расбросан по тыще мест и везде дилитор я подменить не могу


2) Пулятся char[]
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741644
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenА если пулится char[] ?

Пул для chаr[] это стандартный менеджер памяти. Ты не сможешь продублировать его
функциональность в улучшенном варианте.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741662
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenerror: call to implicitly-deleted copy constructor of 'pool_ptr<t, std::__1::default_delete<t> >' ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);

Добавьте еще эти конструкторы, чтобы реализовать move-семантику (copy-семантика не поддерживается в базовом unique_prt, поэтому ее нет смысла пытаться делать).
Код: plaintext
1.
2.
   pool_ptr() = default;
   pool_ptr(pool_ptr&&) = default;
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741664
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя как выше сказали, наследование здесь не нужно.

Вот то же самое как правильно )))
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
template<typename T>
struct PoolDeleter {
    void operator()(T* ptr)
    {
       // return to pool
    }
};

template<typename T>
using pool_ptr = std::unique_ptr<T, PoolDeleter<T>>;
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741668
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskyнаследование здесь не нужно.

Ну вот, лишил ТСа часов отладки и биения головой об стену...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741746
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovsemen.s.semenА если пулится char[] ?

Пул для chаr[] это стандартный менеджер памяти. Ты не сможешь продублировать его
функциональность в улучшенном варианте.


У нас страшно течет RSS хотя утечек Valgrind не показывает

Хочу вместе аллокации - деаллокации испольщовать пул чар-массивов

Это будет лучше чем то что сейчас
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741747
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskysemen.s.semenerror: call to implicitly-deleted copy constructor of 'pool_ptr<t, std::__1::default_delete<t> >' ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);

Добавьте еще эти конструкторы, чтобы реализовать move-семантику (copy-семантика не поддерживается в базовом unique_prt, поэтому ее нет смысла пытаться делать).
Код: plaintext
1.
2.
   pool_ptr() = default;
   pool_ptr(pool_ptr&&) = default;



А почему move конструкторы не отнаследовались от  std::unique_ptr ?
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741748
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenУ нас страшно течет RSS хотя утечек Valgrind не показывает
Хочу вместе аллокации - деаллокации испольщовать пул чар-массивов

Значит у вас копятся не освобождённые ресурсы. Пул тут не поможет, только отладка.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741749
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovsemen.s.semenУ нас страшно течет RSS хотя утечек Valgrind не показывает
Хочу вместе аллокации - деаллокации испольщовать пул чар-массивов

Значит у вас копятся не освобождённые ресурсы. Пул тут не поможет, только отладка.


Вот тут пишут что необязательно

https://stackoverflow.com/questions/23077525/resident-memory-increase-while-valgrind-not-showing-any-leaks

И пулирование как раз спасает от такого

Монитор памяти показывает что у нас очень часто аллоцируется - освобождается пара мелких буферов по 8кб

При стресс тестирование суммарно капает под несколько гигов - хотя реально там меньше мегабайта надо

Хочу облегчить операционке жизнь и посмотреть будет ли после этого течь RSS
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741755
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenА почему move конструкторы не отнаследовались от  std::unique_ptr ?

https://en.cppreference.com/w/cpp/language/move_constructor
авторImplicitly-declared move constructor

If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
- there are no user-declared copy constructors;
- there are no user-declared copy assignment operators;
- there are no user-declared move assignment operators;
- there are no user-declared destructors;
- the implicitly-declared move constructor is not defined as deleted due to conditions detailed in the next section

then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).

У вас деструктор объявлен, поэтому неявного move- не было.
А наследование тут не причем.
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741757
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskysemen.s.semenА почему move конструкторы не отнаследовались от  std::unique_ptr ?

https://en.cppreference.com/w/cpp/language/move_constructor
авторImplicitly-declared move constructor

If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
- there are no user-declared copy constructors;
- there are no user-declared copy assignment operators;
- there are no user-declared move assignment operators;
- there are no user-declared destructors;
- the implicitly-declared move constructor is not defined as deleted due to conditions detailed in the next section

then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).

У вас деструктор объявлен, поэтому неявного move- не было.
А наследование тут не причем.

Спасибо - теперь ясно
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741771
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenВот тут пишут что необязательно

SO, конечно, хороший ресурс, но даже там попадаются странные ответы. Особенно на странные
вопросы. Если valgring не показывает тебе утечку, то вариантов два:
1. Память не потеряна, она по-прежнему где-то внутри твоей программы отслеживается. В этом
случае поможет только долгая и тщательная отладка.
2. Ты как-то неправильно им пользуешься.

Первый случай гораздо вероятнее. Так что включай мозг и начинай анализировать свою программу.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741773
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovsemen.s.semenВот тут пишут что необязательно

SO, конечно, хороший ресурс, но даже там попадаются странные ответы. Особенно на странные
вопросы. Если valgring не показывает тебе утечку, то вариантов два:
1. Память не потеряна, она по-прежнему где-то внутри твоей программы отслеживается. В этом
случае поможет только долгая и тщательная отладка.
2. Ты как-то неправильно им пользуешься.

Первый случай гораздо вероятнее. Так что включай мозг и начинай анализировать свою программу.


Программа не моя

Это внешний   OpenSource продукт - очередное Г

Пулирование - это просто способ проверить поведение если убрать эту аллокацию - деаллокацию.
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741774
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov1. Память не потеряна, она по-прежнему где-то внутри твоей программы отслеживается. В этом
случае поможет только долгая и тщательная отладка.


Ага еще скажи - бага в мониторе памяти.

Ясно вижу что аллоцируемая память - освобождается.

А вот почему при это RSS растет - есть тайна превеликая
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741775
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
The heap is part of your "res" memory, so if you have something that allocates x MB of heap memory, then releases it, unless the OS actually need that memory for other purposes, it will remain as part of your applications memory. (Actually, it's quite a bit more complex than that, but for this discussion, this picture is valid).
...
Рейтинг: 0 / 0
Пул на базе unique_ptr
    #39741781
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никто не отменял фрагментацию кучи, при которой память растет, а утечки нет.
...
Рейтинг: 0 / 0
25 сообщений из 63, страница 1 из 3
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пул на базе unique_ptr
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]