Переопределение обхода оператора, нового в переполнении стека

Есть ли способ добиться обхода переопределения 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 исправить:
Использование нормального нового в переопределении, как этот вопрос задает.

4

Решение

Есть ли способ добиться обхода переопределения оператора new?

Ничего из того, что мне известно, но почему бы вам просто не перестроить ее в своей пользовательской функции таким же образом, как MS сделала это в их реализации на основе _heap_alloc, и просто добавить к ней свою настройку?

Одна только попытка распределения «сделай или умри» в любом случае не то, что делает MS:

http://msdn.microsoft.com/en-us/library/vstudio/we2zys4d.aspx

Поведение по умолчанию — выполнить цикл. Внутри цикла
Функция сначала пытается выделить запрошенное хранилище

Во всяком случае, я второй, что н.м. добавить комментарий

Вам нужно исправить реальные ошибки памяти

Это самоочевидно; для любых целей отладки — просмотрите std :: set_new_handler.

Кстати, есть некоторые вещи, которые меня раздражают в вашем коде

  • явные квалификации оператора
  • не выбрасывает std :: bad_alloc, а перебрасывает вне блока catch

Счастливого взлома!

С уважением, С.

P.S.:@all: Я не могу «проголосовать» за этот вопрос из-за моего ограниченного опыта, но я рекомендую это сделать. Это очень интересная тема и хорошо сформулированная.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]