перегрузка новой / удаление проблемы - PullRequest
0 голосов
/ 06 мая 2010

Это мой сценарий, я пытаюсь перегрузить новое и удалить глобально. Я написал свой класс распределителя в файле с именем allocator.h. И я пытаюсь добиться того, чтобы, если файл включал этот заголовочный файл, нужно использовать мою версию new и delete.

Итак, в заголовочном файле "allocator.h" я объявил две функции

extern void* operator new(std::size_t size);
extern void operator delete(void *p, std::size_t size);

У меня тот же заголовочный файл, у меня есть класс, который выполняет все функции распределителя,

class SmallObjAllocator
{
    ...
};

Я хочу вызвать этот класс из функций new и delete и хотел бы, чтобы класс был статическим, поэтому я сделал это:

template<unsigned dummy>
struct My_SmallObjectAllocatorImpl
{
    static SmallObjAllocator myAlloc;
};

template<unsigned dummy>
SmallObjAllocator My_SmallObjectAllocatorImpl<dummy>::myAlloc(DEFAULT_CHUNK_SIZE, MAX_OBJ_SIZE);

typedef My_SmallObjectAllocatorImpl<0> My_SmallObjectAllocator;

и в файле cpp это выглядит так: allocator.cc

void* operator new(std::size_t size)
{

    std::cout << "using my new" << std::endl;

    if(size > MAX_OBJ_SIZE)
        return malloc(size);
    else
        return My_SmallObjectAllocator::myAlloc.allocate(size);
}

void operator delete(void *p, std::size_t size)
{
    if(size > MAX_OBJ_SIZE)
        free(p);
    else
        My_SmallObjectAllocator::myAlloc.deallocate(p, size);
}

Проблема заключается в том, что я пытаюсь вызвать конструктор для класса SmallObjAllocator, который является статическим объектом. По какой-то причине компилятор вызывает мою перегруженную функцию новой при ее инициализации. Затем он пытается использовать My_SmallObjectAllocator :: myAlloc.deallocate (p, size); который не определен, поэтому программа вылетает.

Так почему компилятор вызывает new, когда я определяю статический объект? и как я могу это решить?

1 Ответ

2 голосов
/ 06 мая 2010

Вы не можете использовать глобальную библиотеку времени выполнения operator new, если предоставите свою собственную. Таким образом, вы не можете использовать new для реализации new, даже при инициализации. Использование разных operator new в разных исходных файлах является нарушением правила одного определения.

Исключить вызов new из конструктора SmallObjAllocator::SmallObjAllocator или реализовать специальный случай, активируемый глобальным bool new_uninitialized или локальным static bool new_is_recursing флагом.

...