2009-09-08 4 views
5

Я пытаюсь написать профилировщик памяти и до сих пор мог использовать мои пользовательские функции для работы в malloc, free, new и delete. Я попытался использовать __FILE__ и __LINE__, чтобы зарегистрировать отправителя внутри перегруженного нового метода, но (как и ожидалось) он просто дает информацию о том, где находится перегруженная функция. Есть ли способ получить информацию об инициаторе для перегруженных функций без каких-либо изменений в существующем коде тестируемого компонента (например, #define для malloc)?Переопределение «новых» и протоколирование данных о вызывающем абоненте

Функция я использую:

void* operator new (size_t size) 
{ 
    if(b_MemProfStarted) 
    { 
     b_MemProfStarted = false; 
     o_MemLogFile << "NEW: " << "| Caller: "<< __FILE__ << ":" 
       << __LINE__ << endl; 
     b_MemProfStarted = true; 
    } 

    void *p=malloc(size); 
    if (p==0) // did malloc succeed? 
    throw std::bad_alloc(); // ANSI/ISO compliant behavior 

    return p; 
} 

BOOL b_MemProfStarted используется, чтобы избежать рекурсивных вызовов на ofstream и map.insert.

ответ

3

Вы можете написать

new(foo, bar) MyClass; 

В этом случае следующая функция называется

void*operator new(std::size_t, Foo, Bar){ 
    ... 
} 

Теперь вы можете позвонить

new(__LINE__, __FILE__) MyClass; 

и использовать данные с

void*operator new(std::size_t, unsigned line, const char*file){ 
    ... 
} 

Добавление макро

#define new new(__LINE__, __FILE__) 

к коду отслеживаемому будет ловить большинство вызовов без необходимости изменения исходного кода.

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

+0

Как 'new' это ключевое слово, пытаясь заново определить он с макросом - это неопределенное поведение (исключение для конкретного компилятора). Я предпочитаю условное определение макроса DEBUG_NEW_PLACEMENT для «нормальных» '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Тем не менее, это еще не очень хорошее решение. –

+0

void * operator new (std :: size_t, unsigned line, const char * file) будет терпеть неудачу, потому что «новый» просто принимает size_t. Невозможно использовать «#define new new (__ LINE__, __FILE__)» и оператор переопределить вместе, поскольку он попытается заменить «новое» в определении функции переопределения. void * operator new (std :: size_t) -> void * operator new (__ LINE__, __FILE __)/* рекурсивный? */(Std :: size_t) – Gayan

+0

@Charles Bailey - Не могли бы вы уточнить? Я не знаком с DEBUG_NEW_PLACEMENT Я попробовал «#define new (size) My_New (размер, __FILE__, __LINE__)», но это не похоже на вызов при выполнении «нового» – Gayan

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

  • Нет связанных вопросов^_^