2016-10-21 4 views
2

У меня есть утечка памяти в моей программе. Я заменил все вызовы на mallocnew) вызовами моей собственной функции, которая отслеживает выделенные вещи. В конце программы я сравниваю вещи, выделенные в начале, и те, которые находятся в конце, чтобы получить список всего, что «протекает».Как проверить, заканчивается ли число в значении?

Конечная цель - взять список «утечек» местоположений и поместить их в массив. Каждый раз, когда что-то выделяется, оно проверяется против списка «утечек» адресов, и если есть совпадение, он вызывает специальную функцию, в которой я могу установить точку останова (где я могу затем выяснить, какие объекты протекают и справиться с ними надлежащим образом).

Проблема в том, что первые несколько частей адреса меняются каждый раз, когда программа запускается. Например, в первый раз один «утечка» адреса будет 0x10c10, а в следующий раз он может быть 0x20c10. Последние несколько цифр всегда одни и те же, но первые несколько нет.

Есть ли способ сравнить только последние несколько цифр? Я думал об использовании мод, но я не смог придумать что-нибудь, что сработало. Это обычные целые числа, а не строки или что-то еще.

+0

Как этот 'mod' (я предполагаю, что вы имеете в виду'% ') не работает? Это простая математика, как она не может работать? –

+0

Just mask: 'addr = number & 0x0000FF;' –

+1

Карта памяти разных процессов не гарантируется одинаковой, даже если разные процессы работают с одним и тем же исполняемым файлом. Даже последние бит в любом адресе. –

ответ

4

Вы можете сравнить последние N цифр шестнадцатеричного числа, применив побитовый оператор & к нему с помощью маски, представляющей количество цифр, которое вы хотите сравнить. Например, для сравнения трех последних шестнадцатеричных цифр, нанесите маску из трех F с, как это:

uintptr_t a = ... 
uintptr_t b = ... 
if ((a&0xFFF) == (b&0xFFF)) { 
    ... 
} 

Вы также можете проверить XOR чисел нулей в последних N цифр, например:

if ((a^b)&0xFFF == 0) { 
    ... 
} 

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

Если по какой-либо причине домашнее профилирование является единственным способом, вы можете использовать special macros for retrieving source file locations и сохранить их в хеш-таблице вместе с адресами утечек. Это позволит вам вернуться к месту в исходном коде, ответственном за выделение, без каких-либо манипуляций с адресами.

+0

Спасибо! Забыл о valgrind, я использую это сейчас. Прекрасно работает! –

+0

Стандарт гарантирует только преобразование в/из 'uintptr_t' (и строго только для' void * '), без арифметики по значению. Сказал, что это пахнет XY-проблемой. – Olaf

+0

@Olaf Я согласен с характеристикой XY этой проблемы. Вот о чем идет вторая половина ответа. Благодаря! – dasblinkenlight

Смежные вопросы