New и delete overload - перегруженное удаление вызывается для неправильной памяти

Я пробовал перегрузить глобальные операторы new и delete для своей программы:
Заголовок

void* operator new(std::size_t n);
void* operator new(std::size_t n, const std::nothrow_t&);
void operator delete(void* p);

Реализация

void* allocMemory(std::size_t n) {
    MemoryAllocationRecord** pRecord = static_cast<MemoryAllocationRecord**>(
            malloc(n + sizeof(MemoryAllocationRecord*)));
    if (pRecord == nullptr) return nullptr;
    void* retBlock = static_cast<void*>(pRecord+1);
    *pRecord = nullptr;
    //may set *pRecord to a legal pointer
    return retBlock;
}
void* operator new(std::size_t n) {
    void* ret = allocMemory(n);
    if (ret == nullptr) throw std::bad_alloc();
    return ret;
}
void* operator new(std::size_t n, const std::nothrow_t&) {
    return allocMemory(n);
}

void operator delete(void* p) {
    if (p == nullptr) return;
    MemoryAllocationRecord** pRecord = static_cast<MemoryAllocationRecord**>(p) - 1;
    if (*pRecord != nullptr){
      //may use *pRecord as a legal pointer
    }
    return free(pRecord);
}

Когда я использую это в одном приложении (которое использует библиотеку Qt 5.11), оно работает без проблем. Но в другом приложении деструктор типа библиотеки (QList<QVariant>) вызывает мой перегруженный delete с памятью, которая выглядит следующим образом:

2a 38 02 00 fd fd fd fd*3c 28 5b 00 ...

* отмечает пройденный указатель, поэтому pRecord == 0xfdfdfdfd0002382a (а затем, естественно, вылетает). Достаточно ясно, что fdfdfdfd - это заполнение памяти компилятором для обнаружения повреждений (я запускаю отладочную сборку), но я не понимаю, как и почему это происходит. В случае, если что-то из этого имеет значение, компилятор - MSVC 2017, 64-битный двоичный, ОС - Windows 7, заголовок с перегрузками операторов включен в файл, в котором уничтожается QList<QVariant>.

Возможно все, в том числе упомянутое «одно приложение» с ошибкой. Поэтому без минимальный воспроизводимый пример здесь больше ничего нельзя сказать.

Sam Varshavchik 23.10.2018 12:40

Другими словами, по крайней мере, вы не видите ничего, что могло бы быть ошибкой очень вероятно здесь, например, не перегружать void delete(void*, std::size_t) или не проверять, что в каждом отдельном файле заголовок с перегрузкой оператора включен перед другими заголовками или что-то в этом роде?

Abstraction 23.10.2018 12:55

Может также захотеть перегрузить new[] и delete[]. Какой-то (плохой) код вызывает delete для материала, выделенного с помощью new[], который часто «просто работает» (пока он не работает).

rustyx 23.10.2018 13:02

Пытаясь найти ошибку в коде, легче позволить хорошему компилятору помочь, чем попросить читателя взять на себя роль компилятора. Я попытался кодировать ваш пример и столкнулся с двумя проблемами и получил предупреждения от компилятора. Однако у меня нет возможности узнать, есть ли у вас код, позволяющий обойти эти предупреждения. Я бы только догадывался, чтобы попросить вас объяснить мои ошибки компиляции, потому что мой код не совпадает с вашим. Похоже, это интересная проблема, с которой @SamVarshavchik, похоже, хочет помочь.

Gardener 23.10.2018 13:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
91
0

Другие вопросы по теме

Похожие вопросы

Вызов функции из dll [выражение, предшествующее круглым скобкам очевидного вызова, должно иметь тип функции (указатель на)]
Сборка ARM для Win IoT Core выдает ошибку «не поддерживается»
В любом случае, чтобы подсказать компилятору оптимизировать деструктор scope_failure, когда нет исключения?
Std :: vector :: push_back () не компилируется в MSVC для объекта с удаленным конструктором перемещения
System.TypeLoadException при попытке создать экземпляр COM-объекта C++ внутри пользовательского домена приложения
Ошибка компилятора: более свободный спецификатор выброса для дестуктора
Отправка пользовательских команд на встроенное устройство по локальной сети: символы или целые числа?
Как выбрать правильные архитектурные / дизайнерские шаблоны
Ошибка сегментации - чтение массива инициализированных указателей
Доступ к переменной enum, объявленной в структуре в C++