Как отследить выделения памяти в (особенно новом/удаляющем) C++

Вам нужно добавить свои макросы в Personal.xlsb, чтобы сделать их доступными для всех файлов excel. Выберите «Макроэкономическая книга» в диалоговом окне «Макрос записи», чтобы сделать это быстро.

enter image description here [/g1]

Источник: http://office.microsoft.com/en-in/excel-help/copy-your-macros- к-а-личного-макро-учебное пособие-HA102174076.aspx

30
задан Anteru 13 January 2009 в 10:13
поделиться

11 ответов

Я рекомендовал бы Вам использовать valgrind для Linux. Это поймает не освобожденную память среди других ошибок как запись в освобожденную память. Другая опция является брызговиком, который говорит Вам о не освобожденная память также. Используйте -fmudflap -lmudflap опции с gcc, затем запустите свою программу с MUDFLAP_OPTIONS=-print-leaks ./my_program.

Вот некоторый очень простой код. Это не подходит для сложного отслеживания, но предназначенное, чтобы показать Вам, как Вы сделали бы это в принципе, если бы необходимо было реализовать его сами. Что-то вроде этого (не учел материал, назвав зарегистрированный new_handler и другие детали).

template<typename T>
struct track_alloc : std::allocator<T> {
    typedef typename std::allocator<T>::pointer pointer;
    typedef typename std::allocator<T>::size_type size_type;

    template<typename U>
    struct rebind {
        typedef track_alloc<U> other;
    };

    track_alloc() {}

    template<typename U>
    track_alloc(track_alloc<U> const& u)
        :std::allocator<T>(u) {}

    pointer allocate(size_type size, 
                     std::allocator<void>::const_pointer = 0) {
        void * p = std::malloc(size * sizeof(T));
        if(p == 0) {
            throw std::bad_alloc();
        }
        return static_cast<pointer>(p);
    }

    void deallocate(pointer p, size_type) {
        std::free(p);
    }
};

typedef std::map< void*, std::size_t, std::less<void*>, 
                  track_alloc< std::pair<void* const, std::size_t> > > track_type;

struct track_printer {
    track_type * track;
    track_printer(track_type * track):track(track) {}
    ~track_printer() {
        track_type::const_iterator it = track->begin();
        while(it != track->end()) {
            std::cerr << "TRACK: leaked at " << it->first << ", "
                      << it->second << " bytes\n";
            ++it;
        }
    }
};

track_type * get_map() {
    // don't use normal new to avoid infinite recursion.
    static track_type * track = new (std::malloc(sizeof *track)) 
        track_type;
    static track_printer printer(track);
    return track;
}

void * operator new(std::size_t size) throw(std::bad_alloc) {
    // we are required to return non-null
    void * mem = std::malloc(size == 0 ? 1 : size);
    if(mem == 0) {
        throw std::bad_alloc();
    }
    (*get_map())[mem] = size;
    return mem;
}

void operator delete(void * mem) throw() {
    if(get_map()->erase(mem) == 0) {
        // this indicates a serious bug
        std::cerr << "bug: memory at " 
                  << mem << " wasn't allocated by us\n";
    }
    std::free(mem);
}

int main() {
    std::string *s = new std::string;
        // will print something like: TRACK: leaked at 0x9564008, 4 bytes
}

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

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

Также примечание, как Мир указанный для его решения также, это только покажет утечки, которые вызываются кодом с помощью нашего собственного определенного оператора, new/delete. Таким образом, если Вы хотите использовать их, поместить их объявление в заголовок и включать его во все файлы, за которыми нужно наблюдать.

26
ответ дан Johannes Schaub - litb 11 October 2019 в 12:58
поделиться

Если Вы означаете делать это как осуществление программирования, оно могло бы дать Вам намного больше понимания, чтобы записать Ваш собственный класс (классы) интеллектуального указателя вместо этого, и последовательно использовать их в течение этого проекта (или модуль проекта).

0
ответ дан 11 October 2019 в 12:58
поделиться

Я заметил много другого внимания ответов на то, какие инструменты можно использовать. Я использовал некоторых из них, и они помогают много.

, Но как осуществление программирования, и видя, что Вы работаете с C++, необходимо будет переопределить глобальное новое и удалить, а также malloc, свободный и перевыделение. Вы думали бы, что только новое переопределение и удаляет, был бы достаточно, но станд.:: строка и другие классы, вероятно, будут использовать malloc и особенно перевыделение.

Затем как только Вы имеете в распоряжении это, можно начать добавлять заголовки для проверки на перезаписи памяти, рекордные отслеживания стека на выделение и так далее.

, В целом, я рекомендовал бы пойти с одним из инструментов, упомянутых сюда, но это могла быть забава записать собственную систему.

0
ответ дан Jørn Jensen 11 October 2019 в 12:58
поделиться

Если Вы разрабатываете в соответствии с Linux, одним из лучших инструментов для этого (например, обнаруживаете утечки памяти, отслеживая выделения, сделанные в определенных местах кода), valgrind, особенно его инструмент горного массива. Единственный недостаток - то, что прогоны программы медленнее (или намного медленнее), таким образом, это только полезно для отладки.

0
ответ дан jpalecek 11 October 2019 в 12:58
поделиться

Не непосредственно ответ на Ваш вопрос, но если Вы действительно просто хотите получить список пропущенных объектов "кучи" в конце программы, можно просто запустить программу с valgrind.

Для MS VS можно играть с "куча" CRT Отладки . Не столь простой как valgrind, немного слишком много для объяснения здесь, но может сделать то, что Вы хотите.

1
ответ дан gimpf 11 October 2019 в 12:58
поделиться

На Linux существует по крайней мере два традиционных метода:

  • malloc () и свободный () (и другие связанные с памятью функции) являются слабыми символами, что означает, что можно просто повторно реализовать их, и версии будут использоваться. Для примера реализации: посмотрите электрический забор.
  • С переменной среды LD_PRELOAD, можно переопределить символы (и слабый и сильный) символы в общих библиотеках с символами, найденными в библиотеках, содержавшихся в переменной среды LD_PRELOAD. При компиляции общей библиотеки с malloc (), свободный () и друзья, Вы все установлены. Снова, электрический забор демонстрирует это.

По сути, Вы не только ловите новый и удаляете, но также и функции выделения памяти C-стиля. Я еще не сделал этого на окнах, но я видел методы, чтобы переписать, как DLLs связаны там также (хотя я вспоминаю, что они были довольно неуклюжи).

Примечание однако, что кроме того, что это интересные методы, я рекомендовал бы использовать valgrind, чтобы сделать то, что Вы хотите выше чего-либо еще.

3
ответ дан user52875 11 October 2019 в 12:58
поделиться

Можно использовать код в http://www.flipcode.com/archives/How_To_Find_Memory_Leaks.shtml со следующими модификациями: код, как дали только работает, если у Вас есть один большой гудящий' исходный файл. Я уладил это для другого вопроса на ТАК ( здесь ).

Для запуска, не делают изменение stdafx.h, делают Ваши модификации в Ваших собственных файлах.

Делают отдельный заголовочный файл mymemory.h и помещают Ваших прототипов функции в него, например (обратите внимание, что это не имеет никакого тело ):

inline void * __cdecl operator new(unsigned int size,
    const char *file, int line);

Также в том заголовке, помещенном другие прототипы для AddTrack (), DumpUnfreed (), и т.д., и #defines, определение типа и оператор экстерна:

extern AllocList *allocList;

Затем в новом mymemory.cpp (который также mymemory.h #include), помещает фактическое определение allocList наряду со всеми реальными функциями (не только прототипы) и добавляют что файл к Вашему проекту.

Затем #include "mymemory.h" в каждом исходном файле, в котором необходимо отследить память (вероятно, все они). Поскольку нет никаких определений в заголовочном файле, Вы не получите дубликаты во время ссылки и потому что объявления там, Вы не получите неопределенные ссылки также.

Имеют в виду, что это не отследит утечки памяти в коде, который Вы не компилируете (например, сторонние библиотеки), но он должен сообщить о Ваших собственных проблемах.

10
ответ дан Community 11 October 2019 в 12:58
поделиться

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

отладчики Памяти доступны для большинства общих платформ разработки. Взгляните на PurifyPlus для коммерческого решения, которое работает над Windows и различным Unixes или valgrind для с открытым исходным кодом, который работает над Linux (и потенциально другие операционные системы, но я только когда-либо использовал его на Linux).

, Если Вы полны решимости относительно замены глобальных операторов, взгляните на эта статья .

7
ответ дан Timo Geusch 11 October 2019 в 12:58
поделиться

Для наших проектов C++ платформы Windows я использую VLD, Визуальный Детектор Утечки, который почти слишком легок для реализации, который отслеживает и сообщает относительно утечек памяти, когда приложение выходит - лучший из всех, его свободное и источник доступны. Система может быть установкой для создания отчетов различными способами (дисковый регистратор, IDE, XML и т.д.) и была неоценима для обнаружения утечек в Windows Services, который всегда является проблемой отладить. Таким образом, при поиске портативного решения если Вы желаете к самокрутке, можно, конечно, просмотреть источник для руководства. Надежда это помогает.

Для заключения в кавычки сайта:

Это - очень эффективный способ быстро диагностировать, и зафиксировать, утечки памяти в приложениях C/C++.

http://dmoulding.googlepages.com/vld

3
ответ дан Damien 11 October 2019 в 12:58
поделиться

Если вы разрабатываете под Windows, бесплатный инструмент DebugDiag поможет найти утечки памяти и обработки.

Вам не нужно дополнять свою программу для работы DebugDiag.

http://www.microsoft.com/downloads/details.aspx?FamilyID=28BD5941-C458-46F1-B24D-F60151D875A3&displaylang=en

Хотя это не самая простая и интуитивно понятная программа! Обязательно поищите в Google учебники и инструкции по ее использованию.

3
ответ дан 27 November 2019 в 23:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: