перегрузка нового / удаления

Я делаю небольшой поиск утечек памяти в своей программе, но мой способ перегрузки 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 *, но я не знаю, что с этим делать.


person Brammie    schedule 24.02.2009    source источник
comment
ничего не делает: что ты имеешь в виду? Вы перегрузили оператор, но вы не переопределили оператор по умолчанию new, поэтому new x вызывает новый по умолчанию, а new (filename, line) x вызывает вашу перегруженную версию.   -  person Max Lybbert    schedule 25.02.2009


Ответы (5)


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);
}
person dirkgently    schedule 24.02.2009
comment
Собственно, однажды у меня была на то серьезная причина. У нас была проблема с компилятором, когда он небезопасно использовал кучи через границы DLL. Исправление заключалось в создании настраиваемой версии new, в которой использовалась определенная именованная куча. - person T.E.D.; 24.02.2009
comment
Почему вы не зарегистрировали ошибку и вместо этого решили поиграть с огнем? - person dirkgently; 24.02.2009
comment
Мы сделали. В ответ мы получили что-то вроде того, что библиотеки DLL не очень хорошо работают с перекрестными процессами в нашей системе. В конце концов мы перестали их использовать, но в краткосрочной перспективе это устранило проблему. - person T.E.D.; 24.02.2009
comment
РЖУ НЕ МОГУ. В любом случае, есть лучшие альтернативы глобальной перегрузке new / delete, как я уже упоминал. - person dirkgently; 24.02.2009
comment
Не будет проблем с библиотеками и всем остальным, если вы не попытаетесь освободить выделенную вами память (и наоборот). И STL может использовать настраиваемые распределители памяти. Мы давно используем собственные операторы new / delete в отладочных сборках и не имеем никаких проблем. - person n0rd; 25.02.2009
comment
Да очень верно. Но с этим сложно справиться. Мы тоже используем настраиваемые распределители (и используем уже некоторое время). Я думаю, что выше я упомянул обычай STL. - person dirkgently; 25.02.2009
comment
Почему вы не зарегистрировали ошибку и вместо этого решили поиграть с огнем? Если бы вам когда-либо приходилось работать с продавцом, вы бы знали ответ на этот вопрос. Некоторые лучше, чем другие, некоторые просто поблагодарили бы за отчет об ошибке - он будет исправлен в следующей версии - о, кстати, ваша лицензия не распространяется на следующую версию ... Некоторые могут даже зайти так далеко, чтобы сказать это не ошибка, это особенность, как было заявлено @TED - person Natalie Adams; 14.09.2013

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

#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;
}
person kyku    schedule 24.02.2009
comment
должно быть size_t вместо unsigned int? Я считаю, что на некоторых платформах эти типы не эквивалентны. - person iggy; 30.03.2015
comment
Почему первый аргумент void* operator new (size_t size, const char* filename, int line) size_t? Что мне писать, если я хочу переопределить оператор delete? - person naive231; 13.09.2017
comment
@ naive231: new всегда принимает size в качестве 1-го параметра. Он получает размер в байтах выделяемых данных (в этом примере sizeof(int)). Все, что передается в new, передается во вторичных параметрах - person Remy Lebeau; 22.03.2018
comment
Разве это размещение факела не ново? - person Jack Aidley; 18.11.2018

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

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

void* operator new(size_t);
void operator delete(void*, size_t);
person T.E.D.    schedule 24.02.2009

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

person zvrba    schedule 24.02.2009

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

person Benoît    schedule 24.02.2009