Обнаружение Утечки памяти и новое переопределение?

Вы не можете переопределить статический метод, таким образом делание его абстрактный было бы бессмысленно. Кроме того, статический метод в абстрактном классе принадлежал бы тому классу, а не переопределяющему классу, так не мог использоваться так или иначе.

5
задан Kyle 14 July 2009 в 22:37
поделиться

4 ответа

You can use pragma directives to save and restore the new macro when undefing for overloads. See [MSDN](http://msdn.microsoft.com/en-us/library/hsttss76(VS.71).aspx) for the exact syntax.

E.g.

#pragma push_macro("new")
#undef new
void FAR* operator new(size_t cb);
#pragma pop_macro("new") 

You can put these in headers, e.g.

begin_new_override.h:

#ifdef new
#define NEW_WAS_DEFINED
#pragma push_macro("new")
#undef new
#endif

end_new_override.h:

#ifdef NEW_WAS_DEFINED
#undef NEW_WAS_DEFINED
#pragma pop_macro("new")
#endif

And then

#include "begin_new_override.h"
void FAR* operator new(size_t cb);
#include "end_new_override.h"
10
ответ дан 18 December 2019 в 08:30
поделиться

Попробовать #undef новый перед определением класса а затем #define new new ... снова после.

1
ответ дан 18 December 2019 в 08:30
поделиться

Вместо того, чтобы определять new как нечто иное, почему бы не перегрузить оператор new?

Добавьте эти определения функций где-нибудь в глобальном пространстве имен:

// operator new overloads
void* operator new( const size_t size, const char* file, int line) throw();
void* operator new( const size_t size, const size_t align, const char* file, int line) throw();
void* operator new[]( const size_t size, const char* file, int line) throw();
void* operator new[]( const size_t size, const size_t align, const char* file, int line) throw();

// can't easily overload operator delete
void operator delete( void* ptr ) throw();
void operator delete[]( void* ptr ) throw();

// matched to the operator new overload above in case of exceptions thrown during allocation
void operator delete( void* ptr, const char* file, int line) throw();
void operator delete[]( void* ptr, const char* file, int line) throw();
void operator delete( void* ptr, const size_t align, const char* file, int line) throw();
void operator delete[]( void* ptr, const size_t align, const char* file, int line) throw();

// global new/delete
void* operator new( size_t size ) throw();
void* operator new( size_t size, const std::nothrow_t& ) throw();
void* operator new( size_t size, size_t align ) throw();
void* operator new( size_t size, size_t align, const std::nothrow_t& ) throw();

void* operator new[]( size_t size ) throw();
void* operator new[]( size_t size, const std::nothrow_t& ) throw();

void operator delete( void* ptr, const std::nothrow_t&) throw();
void operator delete[]( void* ptr, const std::nothrow_t&) throw();

Затем вы можете определить свой собственный новый макрос, который обращается к неглобальным версиям и реализует глобальные версии, чтобы утверждать или предупреждать, если они вызваны (чтобы поймать что-то проскальзывающее).

#define MY_NEW(s)    new(s, __FILE__, __LINE__)

Ваши перегрузки на уровне класса будут работать должным образом, если вы вызовете 'new' непосредственно на класс. Если вы хотите вызвать MY_NEW в классе, вы можете, но вам придется переопределить перегрузку в классе в соответствии с вашим новым.

4
ответ дан 18 December 2019 в 08:30
поделиться

Переопределение new через #define на уровне препроцессора - плохая идея, по моему опыту - вы не только нарушаете оператор new , но также размещение new и, вероятно, несколько других вещей.

Если все эти макросы FILE и LINE расширяются повсюду, ваши разделы .rodata и .data переполняются строками файлов и номерами строк. , и генерирует намного больше кода за вызов.

Намного лучше (если приложить больше усилий заранее), чтобы воспользоваться преимуществом существования отладочной информации (например, .pdb файл) и использовать что-то вроде ] DbgHelp библиотека StackWalk64 для сбора информации о стеке.

Перегрузите различные комбинации глобального оператора new и оператора delete (массив, nothrow и т. Д.),пусть они сохраняют и освобождают информацию стека по мере выделения и освобождения памяти.

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

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

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

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

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

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

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

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

4
ответ дан 18 December 2019 в 08:30
поделиться
Другие вопросы по тегам:

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