Comments 25
В режиме отладки добавляется глобальный дефайн malloc -> malloc_log и аналогичные для остальных и, в зависимости от режима отладки, либо всё пишется в лог, либо просто считается баланс выделения-освобождения. Если баланс на выходе не сходится — переключаем в полный лог, в который пишем размер, адрес, файл и строку. Дальше тупой скрипт на perl выдаёт статистику — что не было освобождено или не дай бог освобождено без выделения. Утечки ловятся на раз, т.к. в режиме баланса на отладке он работает всегда. Правда с хитрыми утечками, которые возникают только при редких стечениях обстоятельств работает плохо. Логи, правды, бывают большими. Порой по пол-гига набегало.
Как сделать аналогичное с new придумать не удалось.
Хороший детектор для Visual Studio, в т.ч. для new. Можно подсмотреть как сделано.
http://www.codeproject.com/Articles/9815/Visual-Leak-Detector-Enhanced-Memory-Leak-Detectio
Еще не очень понял — оно работает только с VS или можно куда угодно прикрутить?
однако как показал опыт самый простой способ контролировать память как ни странно старый добрый malloc/free.
Вы описываете не способ контролировать, а способ бороться с последствиями такого "контроля". Не говоря уже о том, что вся статья посвящена как раз тому что утечки и расстрел памяти — разные вещи и раст обещает именно отсутствие второго.
В моей практике (С++) весьма неплохо работают умные указатели в связке с валгриндом — как раз чтобы уменьшить человеческий фактор. Подозреваю, что достаточного опыта для полноценного сравнения с Rust у вас нет. Впрочем, я и сам не сильно дальше "хелоу ворлдов" ушёл, так что спорить не буду. Хотя растовые гарантии мне кажутся весьма полезными.
А что такое «валгринд»?
void* operator new(std::size_t n)
void* operator new[]( std::size_t count )
void operator delete(void* ptr)
void operator delete[]( void* ptr )
Ну и placement new, new(nothrow) если они вам нужны.
Для более корректной работы нужно так же компилировать все сторонние библиотеки, кроме системных вроде libc. Можно и без этого, но он начнёт пропускать ошибки. Так что работают‐то sanitizer’ы быстро, но всё имеет свою цену.
Ну и, собственно, та же проблема (как я понял по обрывкам). Он попытки освобождения повреждённого указателя не видит.
Leak sanitizer всроен в Address: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fsanitize_003dleak-950
Issue: https://github.com/google/sanitizers/issues/118
mpfr_free_cache: http://www.mpfr.org/mpfr-current/mpfr.html#index-mpfr_005ffree_005fcache
Хотя возможно тут я не прав, голый C мне ближе чем ++
(пардон, это было к комментарию про «void* operator new(std::size_t n)»)
gflags -i program.exe +ust
Подставив вместо program.exe имя своей программы, естественно. Это включает для program.exe логирование выделения/удаления блоков в куче со стеком. Это нужно делать ТОЛЬКО перед поиском утечек, т.к. всё будет работать существенно медленней. Потом запускаете программу и выполняете:
umdh -pn:program.exe -f:dump1.txt
Делается первый слепок памяти (все выделенные блоки со стеками). Дали поработать, поутекать памяти, потом делаете:
umdh -pn:program.exe -f:dump2.txt
umdh dump1.txt dump2.txt > diff.txt
В файл diff.txt выводятся все блоки памяти (количество, объём, стек), сгруппированные по стеку, которые либо был выделены и удалены, либо выделены до первого вызова umdh и удалены до второго. В конце нужно не забыть сделать:
gflags -i program.exe -ust
Утечки не нарушают безопасность памяти