перегрузка новая / удалить - PullRequest
24 голосов
/ 24 февраля 2009

Я делаю небольшой искатель утечки памяти в моей программе, но мой способ перегрузки new и delete (а также new [] и delete []) похоже, ничего не делает.

void* operator new (unsigned int size, const char* filename, int line)
{
    void* ptr = new void[size];
    memleakfinder.AddTrack(ptr,size,filename,line);
    return ptr;
}

Способ, которым я перегружен new, показан во фрагменте кода выше. Я думаю, что-то с оператором, возвращающим void *, но я не знаю, что с этим делать.

Ответы [ 6 ]

138 голосов
/ 10 августа 2011

RE:

Никогда не пытайтесь перегрузить новое / удалить глобально

Почему, когда кто-то пытается использовать менее распространенную функцию C ++, кто-то ведет себя так, как будто этого никогда не следует делать?

Это делается постоянно, это довольно часто, и я не работал в компании, которая этого не делала.

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

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

51 голосов
/ 24 февраля 2009

Может быть, вы можете делать что хотите с небольшим количеством препроцессорной магии:

#include <iostream>

using namespace std;

void* operator new (size_t size, const char* filename, int line) {
    void* ptr = new char[size];
    cout << "size = " << size << " filename = " << filename << " line = " << line << endl;
    return ptr;
}

#define new new(__FILE__, __LINE__)

int main() {
    int* x = new int;
}
12 голосов
/ 24 февраля 2009

Я думаю, что проблема здесь в том, что ваш профиль параметров нового не соответствует стандартному оператору new, так что он не скрывается (и, следовательно, все еще используется).

Ваши профили параметров для новых и удаленных должны выглядеть следующим образом:

void* operator new(size_t);
void operator delete(void*, size_t);
6 голосов
/ 24 февраля 2009
void* ptr = new void[size];

Не могу этого сделать. Исправь это.

Никогда не пытайтесь перегрузить новое / удалить глобально. Либо имейте их в базовом классе и извлекайте все ваши объекты из этого класса, либо используйте пространство имен или параметр распределителя шаблонов. Почему, вы можете спросить. Потому что в случае, если ваша программа представляет собой более одного файла и использует STL или другие библиотеки, вы собираетесь испортить.

Вот дистиллированная версия оператора new из VS2005 new.cpp:

void * operator new(size_t size) _THROW1(_STD bad_alloc)
{       // try to allocate size bytes
   void *p;
   while ((p = malloc(size)) == 0)
    if (_callnewh(size) == 0)
     {       // report no memory
        static const std::bad_alloc nomem;
        _RAISE(nomem);
     }

     return (p);
}
4 голосов
/ 24 февраля 2009

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

4 голосов
/ 24 февраля 2009

Правильно ли вы вызываете перегруженный оператор, т.е. передаете ему дополнительные параметры?

...