2016-07-30 2 views
2

Я хочу, чтобы переопределить оператор new иметь эту подпись:Оператор нового возвращения больше памяти, чем просило

void* operator new(size_t bytes, MemoryManager* man); 

и класс MemoryManager выглядит следующим образом:

struct MemoryManager 
{ 
    virtual void* Allocate(size_t bytes) = 0; 
    virtual void Deallocate(void* ptr) = 0; 
}; 

Теперь то, что я хочу сделать имеет перегруженную функцию new, выделяющую больше памяти, чем требуется. И затем в последних нескольких байтах он сохранит указатель на объект MemoryManager, чтобы он знал, какую функцию использовать в моем пользовательском операторе delete. Так это будет выглядеть выделить что-то вроде этого:

__________ 
|   | _ 
|__________| | 
|   | | 
|__________| | 
|   | | <---- Bytes requested for object 
|__________| | 
|   | | 
|__________| | 
|   | _| 
|__________| 
|   | _ 
|__________| | <---- Pointer to MemoryManager 
|   | _| 
|__________| 

Теперь мой реальный вопрос: действительно делает этот результат в неопределенном поведении? Некоторые вещи, которые могли бы быть проблемой:

  • Это может быть определено для new возвращать больше байт, чем запрошенные
  • Вы можете столкнуться с проблемами выравнивания (но те, вероятно, можно преодолеть)
+5

Я не знаю ничего, что запрещает 'new char [10]' возвращать 100 мегабайт памяти. Что-то вроде этого было бы не очень полезно, конечно. Но ничего на C++ не запрещает, AFAIK. –

+3

Традиционно вы делаете это, сохраняя дополнительные данные * до * объекта, потому что при уничтожении вам не задан размер. И это обычная техника. Выделите X дополнительных байтов, напишите материал в первых X байтах, а затем верните X байты в буфер. – Yakk

ответ

9

Это вид вещей довольно распространен. Тем не менее, вы обычно храните дополнительные данные в начале, а не в конце (учитывая максимальную настройку вашей платформы, т. Е. Вам может потребоваться заполнение). На этом языке нет ничего запрещающего то, что вы предлагаете.

4

Из [basic.stc.dynamic.allocation]:

функции

Распределение попытки выделить требуемый объем памяти. Если он успешный, он должен вернуть адрес начала блока хранения, длина которого в байтах должна быть , по крайней мере, такого же размера, как запрашиваемый размер.

Акцент добавлен. Так что да, стандарт позволяет действительной области хранения иметь больше места, чем было строго задано.

Смежные вопросы