|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|
Не освобождается память std::string после использования std::bind06.12.2019, 13:28. Показов 2894. Ответов 27
Метки нет (Все метки)
Всем привет!
Есть система, которая подгружает из внешних библиотек функции, упаковывает их в std::bind и заносит в std::map<std::string, std::function>. В дальнейшем, как это очевидно, по некой произвольной строке мы в map находим нужную нам функцию и ее выполняем. Система написана на С++11 под Linux (Ubuntu 18.04) В самом коде, который реализует этот механизм утечек памяти нет (я надеюсь, проверял разными способами). А вот дальше начинается магия. Если в импортируемой функции буду использовать std::string, то память после выполнения импортированной функции не будет освобождаться. Бодаюсь с этим уже третий день )) Три вопроса: 1. Что за фигня происходит? Может кто-то сталкивался с подобным поведением. 2. Какие инструменты можно использовать для поиска утечек памяти? Может я еще не все испробовал ) 3. Кто готов покопаться в коде системы и поискать ошибку (за вознаграждение, естественно)?
0
|
|
| 06.12.2019, 13:28 | |
|
Ответы с готовыми решениями:
27
Std::string портит память Освобождение памяти после std:bind
|
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
||
| 06.12.2019, 15:49 | ||
|
Покажи эту функцию
0
|
||
|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|||||||||||
| 07.12.2019, 22:07 [ТС] | |||||||||||
|
Печаль всей ситуации в том, что не важно, что внутри... Изначально был код, который открывал один файл, что-то с ним делал и записывал в другой файл. Вот такой код в системе выполняется бесконечно (сам на себя зациклен):
Сейчас я свел все к такой примитивной штуке:
0
|
|||||||||||
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
||||||||
| 08.12.2019, 11:10 | ||||||||
|
Я так понимаю, ты используешь gcc. Не знаю, как смотреть там утечки (обычно достаточно посмотреть код), но может вот это поможет https://github.com/google/sani... kSanitizer Ну и, если уж создаёшь динамические объекты, пользуйся std::unique_ptr
0
|
||||||||
|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|
| 08.12.2019, 12:04 [ТС] | |
|
Спасибо за рекомендации!
Как вы правильно написали, в приведенном коде ошибок нет. Но достаточно убрать из функции код работы со строкой, как утечка памяти прекращается. Соответственно, утечек памяти ни в sendMessage, ни в Json парсере нет. Может ли это быть связано с тем, что функция вызывается не напрямую, а через std::bind?
0
|
|
|
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
|
|
| 08.12.2019, 13:14 | |
|
igor_goryachev, в вашей ситуации их общих рекомендаций можно только отметить, что лучше не передавать объекты стандартной библиотеки через границы модулей. Это чревато нарушением ODR и последующим за этим неопределенным поведением программы.
0
|
|
|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|||||||||||
| 10.12.2019, 13:56 [ТС] | |||||||||||
|
Я передаю за пределы модулей объекты. Может в этом проблема )
1. Есть основная программа. В ней реализован некоторый базовый класс и "реестр" подключаемых библиотек. 2. Внутри каждой библиотеки реализован один класс (наследуемый от базового). Сам класс передается в основную программу примерно так:
0
|
|||||||||||
|
фрилансер
6465 / 5679 / 1131
Регистрация: 11.10.2019
Сообщений: 15,121
|
|
| 10.12.2019, 14:04 | |
|
igor_goryachev, с объектом класса должен работать тот модуль, который его создал. Тот же самый модуль должен и удалять объект. Наружу можно передавать указатель на созданный объект. На любой чих нужно передавать указатель в создавший объект модуль, чтобы тот модуль вызвал нужную функцию объекта
Это всё потому, что std::string в одном модуле может быть устроен совсем иначе, чем std::string в другом, если это разные процессы
0
|
|
|
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
|
||
| 10.12.2019, 14:15 | ||
|
Нарушение ODR как правило не диагностируется, и далеко не всегда приводит к видимым проблемам. Этим оно и опасно.
0
|
||
|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|||||||||||
| 10.12.2019, 14:15 [ТС] | |||||||||||
|
Процесс один. Потоки разные...
Спасибо за указание куда думать. Фактически, сейчас у меня библиотека отдает основной программе "право" создавать и управлять классом, который реализован в этой библиотеке. Нужно же переписать, что управление жизненным циклом должно быть реализовано в библиотеках, а основная программа должна просто вызывать соответствующие импортированные из библиотек функции? Грубо говоря, вместо
0
|
|||||||||||
|
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
|
|
| 10.12.2019, 14:22 | |
|
igor_goryachev, есть отличная книга, Martin Reddy - API Design for C++.
Там есть ответы на почти все вопросы о том, как правильно дизайнить библиотеки и плагины с использованием С и С++.
2
|
|
|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|
| 10.12.2019, 14:25 [ТС] | |
|
Спасибо, почитаю
0
|
|
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||||||||
| 11.12.2019, 10:52 | ||||||||
|
кто память выделял, тот и должен её освобождать. схема выглядит примерно так:
на стороне модуля - другой. если выделять память одним, а освобождать другим, то утечки памяти - это ты ещё легко отделался.
0
|
||||||||
|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|
| 11.12.2019, 16:57 [ТС] | |
|
hoggy, Все манипуляции со строкой происходят в пределах одной функции. За пределы модуля передается объект. Функция объекта оборачивается в std::bind и много раз вызывается. Т.е. строка там где создается там и удаляется. передачи строки за границы модуля (даже функции) не осуществляется.
Добавлено через 2 минуты Я сейчас читаю рекомендованную книжку и с нуля пишу весь код, собирая его по кусочкам ) Теперь постараюсь ошибок подобных не совершить
0
|
|
|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|
| 12.12.2019, 17:27 [ТС] | |
|
DrOffset, oleg-m1973, hoggy
Всем привет! Переписал я свой код с учетом всех рекомендаций. Запустил. Модули динамически загружаются, функции вызываются, память освобождается. Полная красота и гармония! В однопоточном режиме. Запустил это все дело на пуле потоков и получил утечку памяти ( Видимо, дело в пуле потоков
0
|
|
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
|
| 12.12.2019, 17:36 | |
|
0
|
|
|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|
| 12.12.2019, 17:41 [ТС] | |
|
oleg-m1973, Почему? В однопоточном режиме все отлично же
0
|
|
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
|
| 12.12.2019, 17:43 | |
|
0
|
|
|
0 / 0 / 0
Регистрация: 02.02.2016
Сообщений: 14
|
|||||||||||||||||||||
| 12.12.2019, 20:37 [ТС] | |||||||||||||||||||||
|
Уважаемые знатоки!
Вот какой вопрос ) Есть примитивный до безумия класс:
Немного меняю код
Внимание вопрос. Почему???
0
|
|||||||||||||||||||||
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
||
| 12.12.2019, 21:09 | ||
|
0
|
||
| 12.12.2019, 21:09 | |
|
Помогаю со студенческими работами здесь
20
std::string, std::fstream, ошибка кучи ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri
Как можно еще использовать std::placeholders вне в связки с std::bind? В чем отличия между std::cref() и std::bind()? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
|
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений.
9TO2GP2bpX4
a42b81fb172ffc12ca589c7898261ccb/
https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/
Слева синяя линия -. . .
|
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. .
Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
|
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла:
Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
|
|
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога
Финальные проекты на Си и на C++:
finish-text-sdl3-c. zip
finish-text-sdl3-cpp. zip
|
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
|
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo
Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло.
Но на выплатах по больничным это. . .
|
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Данные берутся из. . .
|