как вы боретесь с утечками памяти?
От: ksd Россия  
Дата: 13.12.17 16:01
Оценка:
коллеги, кто хочет и может, поделитесь, пожалуйста, вашими методами борьбы с утечками памяти и работой с кривыми указателями в ваших проектах.
например, выделяете память строго через ваши аллоки, перегружаете new или что то еще более интересное?
что имею в виду под борьбой с кривыми указателями, например:
void foo(HANDLE h) {
   std::vector<char> v;
   DWORD size = GetFileSize(h, 0);
   v.resize(size);
   ReadFile(h, &v[0], ... // исключение, если size == 0

т.е. такие случаи, когда небезопасно извлекается указатель из чего-то, как в примере.
может, тоже есть какая то система, например, помечать все такие места чем-то, как то так:
#define GET_PTR(x) x
void foo(HANDLE h) {
   std::vector<char> v;
   ...
   ReadFile(h, GET_PTR(&v[0]), ...

-- когда что то непонятное падает, легко поиском по исходникам найти все такие места затем, что когда проект разросся, перелопачивать все исходники в поисках такого проблематично.
спасибо за любые мнения и рекомендации!
Re: как вы боретесь с утечками памяти?
От: alpha21264 СССР  
Дата: 13.12.17 16:06
Оценка: +2
Здравствуйте, ksd, Вы писали:

ksd>коллеги, кто хочет и может, поделитесь, пожалуйста, вашими методами борьбы с утечками памяти и работой с кривыми указателями в ваших проектах.


Использую valgrind. Да, я живу в Линуксе.

Течёт вода Кубань-реки куда велят большевики.
Re: как вы боретесь с утечками памяти?
От: andrey.desman  
Дата: 13.12.17 16:41
Оценка:
Здравствуйте, ksd, Вы писали:

ksd>коллеги, кто хочет и может, поделитесь, пожалуйста, вашими методами борьбы с утечками памяти и работой с кривыми указателями в ваших проектах.

ksd>например, выделяете память строго через ваши аллоки, перегружаете new или что то еще более интересное?
ksd>что имею в виду под борьбой с кривыми указателями, например:
ksd>
ksd>void foo(HANDLE h) {
ksd>   std::vector<char> v;
ksd>   DWORD size = GetFileSize(h, 0);
ksd>   v.resize(size);
ksd>   ReadFile(h, &v[0], ... // исключение, если size == 0
ksd>

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

Основная небезопасность здесь — это доверие внешним данным. Для 0 просто криво, а для больших и очень больших файлов есть варианты.
Re: как вы боретесь с утечками памяти?
От: antropolog  
Дата: 13.12.17 20:48
Оценка:
Здравствуйте, ksd, Вы писали:

ksd>коллеги, кто хочет и может, поделитесь, пожалуйста, вашими методами борьбы с утечками памяти и работой с кривыми указателями в ваших проектах.

ksd>например, выделяете память строго через ваши аллоки, перегружаете new или что то еще более интересное?

хз, просто культура кода.

Ну например здесь:

ksd>что имею в виду под борьбой с кривыми указателями, например:

ksd>
ksd>void foo(HANDLE h) {
ksd>   std::vector<char> v;
ksd>   DWORD size = GetFileSize(h, 0);
ksd>   v.resize(size);
ksd>   ReadFile(h, &v[0], ... // исключение, если size == 0
ksd>


было бы так
void foo(HANDLE h) {
   std::vector<char> v;
   DWORD size = GetFileSize(h, 0);
   assert(size); <-- чекаем логику ассертом, можно кастомным, который пишет в лог + бросает исключение в релизе
   v.resize(size);
   ReadFile(h, &v.at(0), ...); <--- at подстелит соломки если строка переедет в другую логику
}
Re: как вы боретесь с утечками памяти?
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 14.12.17 07:04
Оценка: +1
Здравствуйте, ksd, Вы писали:

ksd>спасибо за любые мнения и рекомендации!

Очевидно, умные указатели, контейнеры и свои обёртки для управления ресурсами вроде MutexLock если нет в либе.
Sic luceat lux!
Re[2]: как вы боретесь с утечками памяти?
От: Мёртвый Даун Россия  
Дата: 14.12.17 07:31
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, ksd, Вы писали:


ksd>>спасибо за любые мнения и рекомендации!

K>Очевидно, умные указатели, контейнеры и свои обёртки для управления ресурсами вроде MutexLock если нет в либе.

Это как раз НЕ очевидно. В таких высоко уровневых трудно бывает чтото найти и диагностировать. По мне так лучше чтобы приложение упало и сняло дамп, я пойму где и устраню. Иначе если ошибка произойдет, пусть и логическая, но приложение продолжило работу, по цепочки остальные модули будут работать с ошибкой.
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Re[3]: как вы боретесь с утечками памяти?
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 14.12.17 07:45
Оценка:
Здравствуйте, Мёртвый Даун, Вы писали:

МД>Это как раз НЕ очевидно. В таких высоко уровневых трудно бывает чтото найти и диагностировать. По мне так лучше чтобы приложение упало и сняло дамп, я пойму где и устраню. Иначе если ошибка произойдет, пусть и логическая, но приложение продолжило работу, по цепочки остальные модули будут работать с ошибкой.

Для этого придумали ассерты.
Sic luceat lux!
Re[3]: как вы боретесь с утечками памяти?
От: antropolog  
Дата: 14.12.17 07:51
Оценка:
Здравствуйте, Мёртвый Даун, Вы писали:

МД>Иначе если ошибка произойдет, пусть и логическая, но приложение продолжило работу, по цепочки остальные модули будут работать с ошибкой.

по какой такой цепочке? откуда она взялась? какова вероятность возникновения такой цепочки? хорошо ли ронять приложение, в котором ошибка в диалоге печати? а если это бекэнд держащий тысячи соединений, надо ронять их все из-за ошибки в одном из них?
Re[2]: как вы боретесь с утечками памяти?
От: Doom100500 Израиль  
Дата: 14.12.17 09:07
Оценка:
Здравствуйте, alpha21264, Вы писали:


A>Использую valgrind. Да, я живу в Линуксе.


А для винды есть umdh ( да, я на две семьи живу )
Спасибо за внимание
Re[3]: как вы боретесь с утечками памяти?
От: alpha21264 СССР  
Дата: 14.12.17 09:37
Оценка:
Здравствуйте, Doom100500, Вы писали:

A>>Использую valgrind. Да, я живу в Линуксе.


D>А для винды есть umdh ( да, я на две семьи живу )


Даже интересно стало.
А он только утечки ловит, или выход за границы массива тоже?

Течёт вода Кубань-реки куда велят большевики.
Re: как вы боретесь с утечками памяти?
От: кт  
Дата: 14.12.17 10:15
Оценка:
Здравствуйте, ksd, Вы писали:

ksd>спасибо за любые мнения и рекомендации!


Иногда борются самыми экзотическими способами, например:

http://rsdn.org/article/pl1/PL1ex10/pl1ex10-2.xml
Автор(ы): Караваев Дмитрий Юрьевич
Дата: 30.12.2013
Статья посвящена описанию добавленных в системную библиотеку средств контроля целостности внутренней структуры «кучи» при выделении и освобождении памяти в программе с возможностью поиска причины нарушения.
Re[2]: так расскажите мне про культуру, пожалуйста!
От: ksd Россия  
Дата: 14.12.17 10:44
Оценка:
A>хз, просто культура кода.

да! но это не просто культура, а довольно объемный кодекс того, как что кодировать. было бы интересно послушать ваш рассказ про вашу культуру.
Re[4]: как вы боретесь с утечками памяти?
От: Doom100500 Израиль  
Дата: 15.12.17 06:05
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>Здравствуйте, Doom100500, Вы писали:


A>>>Использую valgrind. Да, я живу в Линуксе.


D>>А для винды есть umdh ( да, я на две семьи живу )


A>Даже интересно стало.

A>А он только утечки ловит, или выход за границы массива тоже?

Только утечки
Спасибо за внимание
Re: как вы боретесь с утечками памяти?
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.12.17 06:12
Оценка:
Здравствуйте, ksd, Вы писали:

ksd>коллеги, кто хочет и может, поделитесь, пожалуйста, вашими методами борьбы с утечками памяти и работой с кривыми указателями в ваших проектах.

ksd>например, выделяете память строго через ваши аллоки, перегружаете new или что то еще более интересное?

Аккуратностью. Например, если я пишу malloc(), то сразу же пишу симметричный ему free(), не откладывая на потом. Кстати, с утечкой файловых хендлов это тоже работает.
Re[2]: как вы боретесь с утечками памяти?
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.12.17 06:13
Оценка: +1
Здравствуйте, alpha21264, Вы писали:

A>Использую valgrind. Да, я живу в Линуксе.


Valgrind — это все же спороб убедиться, что борьба с утечками была успешна, а не способ самой борьбы...
Re[3]: так расскажите мне про культуру, пожалуйста!
От: Igore Россия  
Дата: 15.12.17 06:27
Оценка:
Здравствуйте, ksd, Вы писали:

A>>хз, просто культура кода.

ksd>да! но это не просто культура, а довольно объемный кодекс того, как что кодировать. было бы интересно послушать ваш рассказ про вашу культуру.
Рассказ очень короткий, RAII + smart_pointers, для WinApi он тоже подходит
  Скрытый текст
Buffer getCertInfo( HCRYPTMSG msg, DWORD index )
{
     DWORD size;

     if( !::CryptMsgGetParam( 
          msg, 
          CMSG_SIGNER_CERT_INFO_PARAM, 
          index, 
          0, 
          &size ) )
     {
          BOOST_THROW_EXCEPTION( std::system_error( ::GetLastError(), errorCategory() ) );
     }

     BOOST_ASSERT( size > 0 );
     std::vector< char > buff( size );

     if( !::CryptMsgGetParam( 
          msg, 
          CMSG_SIGNER_CERT_INFO_PARAM, 
          index, 
          buff.data(), 
          &size ) )
     {
          BOOST_THROW_EXCEPTION( std::system_error( ::GetLastError(), errorCategory() ) );
     }

     return buff;
}
// плюс свои обертки 
class HcryptprovCleaner : boost::noncopyable
{
public:
     HcryptprovCleaner( HCRYPTPROV h )
          : h_( h )
     {
          BOOST_ASSERT( h_ );
     }

     ~HcryptprovCleaner()
     {
          ::CryptReleaseContext( h_, 0 );
     }

private:
     HCRYPTPROV h_;
};
Re: как вы боретесь с утечками памяти?
От: okman Беларусь https://searchinform.ru/
Дата: 15.12.17 07:24
Оценка: 6 (3) +5
Здравствуйте, ksd, Вы писали:

ksd>коллеги, кто хочет и может, поделитесь, пожалуйста, вашими методами борьбы с утечками памяти и работой с кривыми указателями в ваших проектах.

ksd>например, выделяете память строго через ваши аллоки, перегружаете new или что то еще более интересное?

1. Любые ресурсы, которые в принципе могут "течь", — память, дескрипторы, блокировки, коннекты, парные вызовы
типа acquire/release и т.п., — помещаются в RAII-обертки, либо становятся частью классов, API которых тем или
иным образом гарантирует очистку и который нельзя использовать как-то иначе.

Пожалуй, это один из главных принципов. Если в системе нет сложных и хитроумно связанных друг с другом структур
данных, например графов, то уже одно это гарантирует отсутствие утечек на большей части программного кода.

2. Для более сложных случаев используется паттерн "registry": каждый объект при создании регистрируется в
"реестре", при разрушении удаляет себя из него. Проблемные участки кода, подозреваемые в утечках, проверяются с
помощью registry, чтобы количество объектов до и после выполнения кода было одинаковым.

3. Юнит-тесты и другие всевозможные тесты. Если они действительно пишутся и обеспечивают приемлемое покрытие, то
значительная часть чисто технических ошибок (опечатки, неудачный копи-паст, невнимательность и т.п.) вылавливаются
на самых ранних стадиях. Кстати, "приемлемое покрытие" — это не обязательно 100%, лично мой опыт показывает, что
обычно достаточно проверок базовых и пограничных случаев, а также проверок всяких failure cases (но соглашусь,
что проверять failure cases сложно и очень часто на это "кладут болт").

4. Иногда применяются специальные аллокаторы, особенно когда нужно протестировать какой-нибудь сложный алгоритм,
интенсивно работающий с памятью. В этом случае подаваемый на вход буфер формируется таким образом, чтобы сразу за
его окончанием (или перед первым байтом) была страница памяти с атрибутами защиты 'NoAccess'. Если произойдет
выход за пределы буфера, пусть даже только на чтение, приложение немедленно вылетит с 'Access Violation'.
К сожалению, в чистом виде применять эту технику не всегда возможно (например, из-за требований к выравниванию).

5. Из других средств: ассерты, SAL-аннотации (в основном для драйверного кода), статические и динамические
анализаторы (PREfast, C++ Code Analyzer, Driver Verifier, Application Verifier), checked-сборки Windows...
Ну и конечно, компиляция на максимальном уровне предупреждений (/W4 /WX), отказ от небезопасных языковых
средств (приведения в стиле C, auto::ptr) и так далее.

Из написанного самое важное — это, пожалуй, пункты 1 и 3. То есть, грамотно построенная архитектура приложения
(в которой обычно сильно сложных взаимосвязей нету) с активным использованием RAII, плюс тестовое покрытие.

Использую эти техники очень давно, с утечками памяти и проблемами "сырых указателей" приходилось серьезно
бороться буквально считанные разы. Хотя, может быть, просто повезло
Re[3]: как вы боретесь с утечками памяти?
От: alpha21264 СССР  
Дата: 15.12.17 09:30
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, alpha21264, Вы писали:


A>>Использую valgrind. Да, я живу в Линуксе.


Pzz>Valgrind — это все же спороб убедиться, что борьба с утечками была успешна, а не способ самой борьбы...


Как-то очень глубокомысленно.
valgrind мне говорит место, где была потеряна память.
Это разве не оно?

Течёт вода Кубань-реки куда велят большевики.
Re[4]: как вы боретесь с утечками памяти?
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.12.17 10:26
Оценка: +1
Здравствуйте, alpha21264, Вы писали:

Pzz>>Valgrind — это все же спороб убедиться, что борьба с утечками была успешна, а не способ самой борьбы...


A>Как-то очень глубокомысленно.

A>valgrind мне говорит место, где была потеряна память.
A>Это разве не оно?

Ну, конечно это помогает жить, когда ты не просто знаешь, что память течет, а понимаешь, какая именно. Сильно сужает круг поиска. Но потом все равно надо головой думать. А если заранее не подумать, то потом будет очень сложно думать.

А вот думать заранее, как сделать так, чтобы память не текла — это и есть сама борьба.
Re[5]: как вы боретесь с утечками памяти?
От: alpha21264 СССР  
Дата: 15.12.17 11:27
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>А вот думать заранее, как сделать так, чтобы память не текла — это и есть сама борьба.


Ну, я использую стратегию "освобождается там, где захватывалось".
Если это про объекты, то симметрия конструктор-деструктор.
Но вот если присутсвуют куски чужого кода, тогда valgrind.

Течёт вода Кубань-реки куда велят большевики.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.