Есть ли способ добиться обхода переопределения operator new
?
Что-то вроде этого:
void* ::operator new( std::size_t size ) {
void *p = ( ::operator new( size ) ); // But original, _not_ infinite recursion
// do stuff with p
return p;
}
Фон:
У меня есть старый код, который мы недавно перешли на компиляцию с Visual Studio 2012. Теперь мы получаем случайные сбои, когда malloc
не в состоянии _heap_alloc
достаточно блоков памяти. (Да, код пропитан небольшими утечками памяти и другим плохим поведением повсюду. Но, к сожалению, тщательная очистка не реалистична, это где-то около 500 000 SLOC.)
Моя текущая теория состоит в том, что причина в том, что почти все исходные файлы содержат заголовок со следующими переопределениями operator new
:
void* ::operator new( std::size_t size ) {
void* p = malloc( size );
if( p == NULL )
throw;
// set memory to zero
memset( p, 0, size );
return p;
};
void* ::operator new[]( size_t count ) throw(std::bad_alloc) {
// try to allocate count bytes for an array
return (operator new(count));
}
Там нет переопределений delete
,
По сути, это означает, что приложение смешивает распределение, используя malloc
с освобождением с использованием delete
вместо free
,
Сначала попробуйте Q&D исправить:
Ввести переопределения delete
который использует free
, Но это только отчасти помогает, потому что иногда включают в себя упорядоченные и связанные библиотеки, которые по-прежнему запутываются.
Вторая попытка Q&D исправить:
Удалить переопределение. Но инициализация памяти к 0, к сожалению, необходима. Наследие старого используемого компилятора, который всегда делал это, и кодеры, которые предполагали, что C ++ всегда будет делать это.
Я знаю, что new () позаботится об этом, но, к сожалению, я не знаю ни одного хорошего способа использовать это без ручного просмотра всего исходного кода и его обновления. Это также не поможет с плохо реализованными классами, которые предполагают, что все их члены обнуляются, не делая этого в конструкторе.
Поэтому моя третья идея Q&D исправить:
Использование нормального нового в переопределении, как этот вопрос задает.
Есть ли способ добиться обхода переопределения оператора new?
Ничего из того, что мне известно, но почему бы вам просто не перестроить ее в своей пользовательской функции таким же образом, как MS сделала это в их реализации на основе _heap_alloc, и просто добавить к ней свою настройку?
Одна только попытка распределения «сделай или умри» в любом случае не то, что делает MS:
http://msdn.microsoft.com/en-us/library/vstudio/we2zys4d.aspx
Поведение по умолчанию — выполнить цикл. Внутри цикла
Функция сначала пытается выделить запрошенное хранилище
Во всяком случае, я второй, что н.м. добавить комментарий
Вам нужно исправить реальные ошибки памяти
Это самоочевидно; для любых целей отладки — просмотрите std :: set_new_handler.
Кстати, есть некоторые вещи, которые меня раздражают в вашем коде
Счастливого взлома!
С уважением, С.
P.S.:@all: Я не могу «проголосовать» за этот вопрос из-за моего ограниченного опыта, но я рекомендую это сделать. Это очень интересная тема и хорошо сформулированная.
Других решений пока нет …