Скажем, я скомпилирую некоторую программу с g++ (используя флаг -g, если это помогает). Я запускаю его, и мой компьютер просто блокируется, что заставляет меня перезапустить. Пользовательский интерфейс у меня просто не работает. Valgrind и gdb делают то же самое.
Я могу поместить вывод в файл и прочитать его, когда я запустил свой компьютер, но это может сделать отладку еще более трудоемким процессом, поскольку я должен перезагружать свой компьютер каждый раз, когда запускаю программу.
В моем случае программа должна занимать незначительный (не более 1/400) процент памяти. Несколько мегабайт в размере.
В C++ вы можете определить глобальный распределитель:
void *operator new(size_t sz);
void *operator new[](size_t sz);
void operator delete(void *p);
void operator delete[](void *p);
и то же самое для не-бросающих версий.
Эти функции будут вызываться каждый раз, когда вам требуется память из кучи, используя new
для экземпляров или массивов.
Что вы можете сделать, так это создать модуль с реализованными функциями, который ограничит общую сумму 100 Мб, а затем сломается с отладчиком, когда этот предел будет передан, чтобы узнать, кто выделяет память.
Обратите внимание, что эти пользовательские функции распределения будут вызываться только для памяти, выделенной new
, а не для памяти, выделенной с помощью malloc
. Также обратите внимание, что вы можете использовать malloc
/free
для реализации своей версии (конечно, вы не можете использовать new
потому что это будет просто рекурсивный вызов).
Один досадный факт состоит в том, что вы должны помнить размер выделенных блоков самостоятельно, потому что нет портативного способа задать размер блока malloc
-ed. Простой способ сделать это - перераспределить, скажем, 8 байт и сохранить размер блока прямо перед выделенной областью памяти.
Вы можете использовать ОС (предположительно, на основе Linux), чтобы помочь вам сбой вашей программы, когда она потребляет слишком много памяти. Там есть ответ на другом сетевом сайте StackExchange о потреблении памяти Limit для одного процесса Linux. Затем вы можете использовать отладчик для отслеживания точки отказа.