3
我想用C來寫內存跟蹤++中進入無限循環。但它正在循環並且一次又一次地呼叫new
。以下是我的代碼。內存跟蹤++超載<code>new</code>和<code>delete</code>操作向量初始化
#ifndef MEMORY_TRACKER_H_
#define MEMORY_TRACKER_H_
#pragma warning(disable : 4290)
#pragma comment(lib, "Dbghelp.lib")
#include <Windows.h>
#include <malloc.h>
#include <map>
#include <iostream>
#include <DbgHelp.h>
#include <sstream>
#include <vector>
static const int MAX_TRACES = 62;
static const int MAX_LENGTH = 256;
static const int BUFFER_LENGTH = (sizeof(SYMBOL_INFO) + MAX_LENGTH * sizeof(wchar_t) + sizeof(ULONG64) - 1)/sizeof(ULONG64);
static bool SYSTEM_INITIALIZED = false;
typedef struct record_t {
std::string symbol;
std::string address;
std::string filename;
std::string linenumber;
} record;
typedef std::vector<record> record_vec_t;
typedef std::pair<size_t, record_vec_t> record_entry_t;
typedef std::map<size_t, record_entry_t> memory_record_t;
memory_record_t gMemoryRecord;
static record_vec_t GetCallStackDetails(const void* const* trace, int count) {
record_vec_t callStackVector;
for (int i = 0; i < count; ++i) {
ULONG64 buffer[BUFFER_LENGTH];
DWORD_PTR frame = reinterpret_cast<DWORD_PTR>(trace[i]);
DWORD64 sym_displacement = 0;
PSYMBOL_INFO symbol = reinterpret_cast<PSYMBOL_INFO>(&buffer[0]);
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_LENGTH;
BOOL has_symbol = SymFromAddr(GetCurrentProcess(), frame, &sym_displacement, symbol);
DWORD line_displacement = 0;
IMAGEHLP_LINE64 line = {};
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
BOOL has_line = SymGetLineFromAddr64(GetCurrentProcess(), frame, &line_displacement, &line);
record curr_rec;
curr_rec.symbol = "(No Symbol)";
std::stringstream formatter;
if (has_symbol) {
curr_rec.symbol = symbol->Name;
formatter.clear();
formatter << " [0x" << trace[i] << "+" << sym_displacement << "]";
curr_rec.address = formatter.str();
} else {
formatter.clear();
formatter << " [0x" << trace[i] << "]";
curr_rec.address = formatter.str();
}
if (has_line) {
formatter.clear();
formatter << line.FileName;
curr_rec.filename = formatter.str();
formatter.clear();
formatter << line.LineNumber;
curr_rec.filename = formatter.str();
}
callStackVector.push_back(curr_rec);
}
return callStackVector;
}
static void addRecord(void *ptr, size_t size) {
if (SYSTEM_INITIALIZED == false) {
SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);
if (SymInitialize(GetCurrentProcess(), NULL, TRUE)) {
SYSTEM_INITIALIZED = true;
} else {
SYSTEM_INITIALIZED = false;
return;
}
}
void* trace[MAX_TRACES];
int count = CaptureStackBackTrace(0, MAX_TRACES , trace, NULL);
record_vec_t record = GetCallStackDetails(trace, count);
record_entry_t entry = std::make_pair(size, record);
gMemoryRecord.insert(std::make_pair((size_t)ptr, entry));
}
static void deleteRecord(void *ptr) {
memory_record_t::iterator itr = gMemoryRecord.find((size_t)ptr);
if (itr != gMemoryRecord.end()) {
gMemoryRecord.erase(itr);
}
}
void dumpUnfreedMemory() {
for (memory_record_t::iterator itr = gMemoryRecord.begin(); itr != gMemoryRecord.end(); ++itr) {
}
}
// Overloading new operator
void* operator new (size_t size) throw (std::bad_alloc) {
std::cout << " Overloaded new is called " << std::endl;
void *ptr = (void *)malloc(size);
addRecord(ptr, size);
return ptr;
}
// Overloading delete Operator
void operator delete (void* ptr) throw() {
std::cout << " Overloaded delete is called " << std::endl;
deleteRecord(ptr);
free (ptr);
}
#endif
下面是測試文件
#include "MemoryTracker.h"
int main (int argc, char **argv) {
int *ptr = new int;
return 0;
}
它進入環上的GetCallStackDetails
電話,平臺是windows
謝謝,我如何指定自定義分配器,使其調用的std ::新的運營商 – Avinash 2012-08-08 18:51:46
的問題是,你剛剛更換'運營商new',所以這是一個它會調用。就像'std :: map','std :: string',還有'std :: stringstream'一樣。實施低級功能時,您不能使用高級功能。考慮一下你是否真的需要實現全局運算符,或者如果你可以爲你想跟蹤的類創建'operator new'。 – 2012-08-08 19:31:17
感謝戴夫S,我理解了這個問題,並刪除了我的代碼中的整個使用STL。 這裏是鏈接[在Windows C++應用程序查找內存泄漏](http://avdongre.wordpress.com/2012/08/09/finding-memory-leak-in-c-application-on-windows/) – Avinash 2012-08-09 10:51:36