Переопределение выделения памяти в MSVStack Overflow

Хотя стандартная среда выполнения Microsoft предоставляет отладочную версию функций выделения, она на самом деле не работает, потому что вы не должны использовать голое нововведение в коде C ++, поэтому инструментарий указывает на стандартную библиотеку, или на нигде, потому что стандартная библиотека в любом случае не может быть оснащена инструментами.

Теперь у меня есть код, который может производить (и записывать) обратные следы распределений, и я также использовал ДУМА. Однако попытки заменить функции выделения потерпели неудачу, когда мы использовали потоки, потому что streambuf вызывает какой-то вариант отладки и делает это непоследовательно между new и delete.

Так есть ли у кого-нибудь опыт замены распределителя путем переопределения функций, а не уродливых приемов препроцессора, в стандартной среде выполнения Microsoft? Я подозреваю, что это включает избегая распределитель отладки, но я хочу сохранить _DEBUG определить по понятным причинам (от этого зависит гораздо больше кода отладки).

Примечание: в настоящее время мы застряли с Visual C ++ 9.0 (Visual Studio 2008).

Редактировать: избегать распределителя отладки вряд ли будет возможным, потому что стандартной библиотеке C ++ необходимо иметь согласованные определения новых и удаленных функций и экземпляров, скомпилированных для библиотеки, и экземпляров, сгенерированных в пользовательском коде, поскольку выделение может выполняться одним и отпусти другим. Это, кстати, означает, что определение статических встроенных вариантов в заголовке с принудительным включением вряд ли приведет к его сокращению.

Edit2: это невозможно с динамическим связыванием, потому что Windows связывает символы из определенных библиотек DLL, поэтому невозможно переопределить их во время соединения. Но нам не нужно динамическое связывание и мы не используем его, потому что основной целью является WinCE, а статическое связывание там по умолчанию.

3

Решение

Вот как мы это делаем (с jemalloc, но возможен любой другой распределитель):

  1. Скомпилируйте пользовательский распределитель памяти отдельно как статическую библиотеку C.
  2. Свяжите свое приложение C ++ с пользовательской библиотекой распределителя.
  3. Переопределить операторы new а также delete в вашем приложении C ++, чтобы вызвать пользовательский распределитель.

Заметки:

  • Пользовательский распределитель должен быть написан на C, а не на C ++.
  • Невозможно обеспечить достаточно раннюю инициализацию распределителя, если он не находится в отдельной библиотеке.
  • Переопределение malloc а также free также возможно, но намного сложнее в MSVC, потому что они не «слабо» связаны, и потому что в MSVC есть много пользовательских вариантов (например, с использованием /FORCE:MULTIPLE флаг компоновщика).

Образец кода:

void* operator new(size_t size)
{
void* ptr = my_malloc(size);
if (ptr)
return ptr;
else
throw std::bad_alloc();
}

void* operator new[](size_t size)
{
void* ptr = my_malloc(size);
if (ptr)
return ptr;
else
throw std::bad_alloc();
}

void* operator new(size_t size, const std::nothrow_t&) throw()
{
return my_malloc(size);
}

void* operator new[](size_t size, const std::nothrow_t&) throw()
{
return my_malloc(size);
}

void operator delete(void* pointer) throw()
{
my_free(pointer);
}

void operator delete[](void* pointer) throw()
{
my_free(pointer);
}

void operator delete(void* pointer, const std::nothrow_t&) throw()
{
my_free(pointer);
}

void operator delete[](void* pointer, const std::nothrow_t&) throw()
{
my_free(pointer);
}
1

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

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector