Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
karat39
6 / 6 / 2
Регистрация: 09.02.2016
Сообщений: 137
#1

Освобождение памяти после std:bind - C++

01.08.2016, 13:49. Просмотров 378. Ответов 11
Метки нет (Все метки)

Что имею:
- CentOS
- gcc 4.8
- valgrind

Что делаю
- С помощью valgrind устраняю утечки
- Если приложение остановлено штатно, то все утечки я устранил
- Если останавливаю с помощью ctrl-c, valgrind рапортует об куче неосвобожденной памяти. Скорее всего, нужно в деструкторах освободить руками.

Проблема
Получаю такой кусок отчета

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
24 bytes in 1 blocks are still reachable in loss record 2 of 6
at 0x4C2A105: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
 
by 0x402FDC: _M_clone (functional:1910)
 
by 0x402FDC: std::_Function_base::_Base_manager<std::[B]_Bind[/B]<std::_Mem_fn<void (MyClassWorker::*)(header_struct*, void*, bool)> (MyClassWorker*, std::_Placeholder<1>, std::_Placeholder<2>, std::_Placeholder<3>)> >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) (functional:1946)
 
by 0x404D3F: function (functional:2442)
 
by 0x404D3F: operator= (functional:2275)
 
by 0x404D3F: MyClass::MyClass(char const*, char const*, unsigned int, char const*, unsigned int, unsigned int, char const*, [B]std::function<void (header_struct*, void*, bool)[/B]>) (MyClass.cpp:49)
 
by 0x4026DD: main (main.cpp:26)
Делаю вывод, что выделение памяти вызвано созданием функции bind (хотя пока писал, быть может память выделилась под ее переменные). Следовательно вопрос, как то можно ее освободить в конструкторе?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.08.2016, 13:49
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Освобождение памяти после std:bind (C++):

Очень долгое освобождение динамически выделенной памяти - C++
Все никак не могу разобраться с одной проблеммой! У меня есть отображение, в котором хранятся указатели на абстрактный класс Node ...

BISON, освобождение памяти при синтаксической ошибке. - C++
Здравствуйте. При работе с BISON, как освободить память выделенную под возвращаемые продукциями &quot;объекты&quot; в случае синтаксической ошибки?...

std::string, std::fstream, ошибка кучи - C++
где то начало вылетать при операции += с локальной переменной std::string. Заменил на свой qString. Замечательно, то же самое... ошибка при...

как проинициализировать std::stack<const int> obj ( std::stack<int>{} ); - C++
добрый день. вопрос в коде: http://rextester.com/VCVVML6656 #include &lt;iostream&gt; #include &lt;stack&gt; //-std=c++14...

std::filesystem && std::asio и пр - C++
Пытался найти хоть какие-то сроки включения всего этого в стандарт (так же ожидается lexical_cast, any, string_algo и т.д.) и вообщем везде...

Освобождение динамически созданных переменных (2-ого уровня) - C++
И так, продолжу старую тему про динамику. На этот раз есть вот что: #include &lt;iostream&gt; #include &lt;stdio.h&gt; #include &lt;conio.h&gt; ...

11
DrOffset
7509 / 4505 / 1023
Регистрация: 30.01.2014
Сообщений: 7,362
01.08.2016, 15:39 #2
Цитата Сообщение от karat39 Посмотреть сообщение
Следовательно вопрос, как то можно ее освободить
Не-не, не все так просто. Оставь пока bind в покое. Ты наблюдаешь симптом, а лечить надо причину.

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

Добавлено через 2 минуты
Цитата Сообщение от karat39 Посмотреть сообщение
Если останавливаю с помощью ctrl-c
При всем при этом, обработка ctrl-c должна быть корректной. В том смысле, что приложение должно быть готово к обработке этого сигнала.
Хоть что-то было сделано в этом направлении?
1
karat39
6 / 6 / 2
Регистрация: 09.02.2016
Сообщений: 137
01.08.2016, 16:10  [ТС] #3
Цитата Сообщение от DrOffset Посмотреть сообщение
В том смысле, что приложение должно быть готово к обработке этого сигнала.
Хоть что-то было сделано в этом направлении?
да, начал сразу же копать в этом направлении. Понял, что нужно обрабатывать руками. Выкрутился через
C++
1
signal(SIGINT, <func>)
В принципе, теперь все стало корректно закрываться, valgrind теперь больше не ругается. Утечки/некорректное использование все устранены.

Еще бы придумать, как простой kill или kill -9 перехватывать и вызывать конструкторы, но я так понимаю не судьба.

Добавлено через 8 минут
В принципе на это тоже есть ответ.
C++
1
signal(SIGTERM, <func>)
Но тогда есть риск получить постоянно зацикленное приложение без возможности вырубания. Если только пройти все циклы руками и вставить проверку на сигнал.
0
DrOffset
7509 / 4505 / 1023
Регистрация: 30.01.2014
Сообщений: 7,362
01.08.2016, 19:16 #4
Цитата Сообщение от karat39 Посмотреть сообщение
<func>
Есть подозрение, что и сейчас у тебя тоже не совсем правильно сделано.

Дело в том, что в функции-обработчики имеют довольно сильные ограничения на свое содержимое. На самом деле внутри них можно делать достаточно мало чего. Например очень плохо, если обработчик занимается выделением или освобождением памяти. Список функций, которые можно из них вызывать есть в мане. Если, например, из обработчика нужно дергать общую с остальным приложением переменную, то она должна быть типа sigatomic_t.

Поэтому более правильным будет либо использовать функции sigwait\sigtimedwait и выполнять ожидание в отдельном для сигналов потоке (пример есть тут), либо использовать события на signalfd (ожидание через poll/select и т.п.) пример есть тут. Оба способа позволяют обрабатывать сигнал в "нормальном" режиме, без ограничений на выполняемые операции. Какой из способов лучше - зависит от архитектуры приложения.
1
karat39
6 / 6 / 2
Регистрация: 09.02.2016
Сообщений: 137
01.08.2016, 19:29  [ТС] #5
Цитата Сообщение от DrOffset Посмотреть сообщение
Дело в том, что в функции-обработчики имеют довольно сильные ограничения на свое содержимое
У меня все очень предельно просто реализовано. Думаю не должно быть проблем. За маны спасибо, вникать я люблю.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool is_exit = false;
 
void signal_func(int _signal) {
    if (_signal != SIGINT) return;
    is_exit = true;
}
 
int main()
{
    signal(SIGINT, signal_func);
    while (true) {
        ...
        ...
        ...
        if (is_exit) break;
    }
}
0
DrOffset
7509 / 4505 / 1023
Регистрация: 30.01.2014
Сообщений: 7,362
01.08.2016, 19:32 #6
Цитата Сообщение от karat39 Посмотреть сообщение
Думаю не должно быть проблем.
bool на sigatomic_t замени.
0
karat39
6 / 6 / 2
Регистрация: 09.02.2016
Сообщений: 137
01.08.2016, 19:34  [ТС] #7
Цитата Сообщение от DrOffset Посмотреть сообщение
ожидание в отдельном для сигналов потоке (пример есть тут)
с этим пока заминка. Задача пока стоит реализовать рабочие алгоритмы в одном потоке.
Реализовать, оттестить и запустить в эксплуатацию. Потом после ходовых испытаний начать распараллеливать. Пока на это табу. Поэтому принципиально не запускаю потоки.

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
bool на sigatomic_t замени
спасибо.
0
DrOffset
7509 / 4505 / 1023
Регистрация: 30.01.2014
Сообщений: 7,362
01.08.2016, 19:38 #8
Цитата Сообщение от karat39 Посмотреть сообщение
Задача пока стоит реализовать рабочие алгоритмы в одном потоке.
Безотносительно этих твоих требований скажу, что этот поток не должен заниматься никакой работой, кроме ожидания сигнала.
Например, в основном (и единственном рабочем) потоке можно сделать очередь событий, в которую помимо насущных задач, иногда будут поступать события, сгенерированные по приходу сигналов из второго потока. В этом смысле у нас второй поток не занимается работой, он только изредка просыпается, если пришел сигнал, и ставит в очередь событие. Важно, чтобы это было понятно. И использовать или не использовать эту технику решалось исходя из архитектуры, а не категоричного запрета на потоки
0
karat39
6 / 6 / 2
Регистрация: 09.02.2016
Сообщений: 137
02.08.2016, 11:13  [ТС] #9
Цитата Сообщение от DrOffset Посмотреть сообщение
bool на sigatomic_t замени
изучил более подробно маны и этот момент, спасибо, дельный был совет.

Цитата Сообщение от DrOffset Посмотреть сообщение
потоке можно сделать очередь событий, в которую помимо насущных задач, иногда будут поступать события .... В этом смысле у нас второй поток не занимается работой, он только изредка просыпается, если пришел сигнал, и ставит в очередь событие
я понимаю, что моя просьба уже будет за пределами темы топика. Не могли бы вы куда нибудь меня отправить изучить/почитать по данной тематике. То что вы описали - это предмет моей будущей задачи. Я пока плавно готовлюсь к ней. Почитываю пока Уильямса "Параллельное программирование в c++". Вы очень четко сформулировали, то что мне надо. Очередь событий, пул потоков, пробуждения, засыпания и тд.
Заранее спасибо.
0
DrOffset
7509 / 4505 / 1023
Регистрация: 30.01.2014
Сообщений: 7,362
02.08.2016, 15:53 #10
Цитата Сообщение от karat39 Посмотреть сообщение
Почитываю пока Уильямса "Параллельное программирование в c++"
По многопоточности можно еще почитать The Art of Multiprocessor Programming. По системным вызовам Linux рекомендую книгу The Linux Programming Interface.

Насчет того, что я выше описал, где-то у меня лежал небольшой пример на эту тему (писался тоже для какой-то демонстрации). Если надо - могу поискать.
0
karat39
6 / 6 / 2
Регистрация: 09.02.2016
Сообщений: 137
02.08.2016, 17:55  [ТС] #11
Цитата Сообщение от DrOffset Посмотреть сообщение
Насчет того, что я выше описал, где-то у меня лежал небольшой пример на эту тему (писался тоже для какой-то демонстрации). Если надо - могу поискать.
был бы признателен.
0
Dmitriy_M
1375 / 1258 / 114
Регистрация: 20.03.2009
Сообщений: 4,499
Записей в блоге: 11
03.08.2016, 22:25 #12
На тему сигналов и потоков есть неплохая статья Доступ к разделяемым атомарным объектам из обработчика сигнала в C
0
03.08.2016, 22:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2016, 22:25
Привет! Вот еще темы с ответами:

Вывод типа, универсальные ссылки, cannot bind lvalue to && и другие - C++
Доброго дня, товарищи. Вот код: Вот отчет компиля: Объясните мне, пожалуйста, где я не прав. Каким образом константный lvalue литерал...

Освобождение памяти - C++ Builder
//--------------------------------------------------------------------------- #ifndef Lariphm_H #define Lariphm_H /* *...

Автоматическое освобождение памяти - C++ Builder
Вот небольшой тестовый примерчик. Это программа, выделяющая для работы 1ГБ памяти. *.h: ...

Удаление объекта (освобождение памяти) - C++ Builder
Здравствуйте все! Имеется следующий код: TForm1* Form1 = new TForm1(); void* form = Form1; delete form; Вопрос: удаление...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru