Запись функции перегрузки для нового оператора - PullRequest
0 голосов
/ 18 ноября 2011

Я написал следующую простую функцию:

void *operator new(size_t size) throw(std::bad_alloc)
{
    void *p;
    p =  malloc(size);
    if(!p)
       throw bad_alloc();
    return p;
}

Что еще я могу сделать, чтобы улучшить это?Будет ли malloc более эффективным, чем new?Если я хочу написать new[] мне нужно только изменить сигнатуру функции?

Ответы [ 3 ]

1 голос
/ 25 июля 2012

Этот код будет работать так, как есть, , но , если вы сделаете это, вам в значительной степени нужно написать соответствующий ::operator delete, который будет работать с ним:

void operator delete(void *block) throw() {
    ::free(block);
}

Лично я бы, вероятно, изменил ваш код на что-то вроде:

void *operator new(size_t size) throw(std::bad_alloc)
{
    void *p =  malloc(size);
    if(!p)
       throw bad_alloc();
    return p;
}

Я предпочитаю инициализировать все, что могу, а не создавать неинициализированную переменную, и только потом присваивать ей значение. В этом случае разница довольно незначительна, но я считаю, что эту привычку стоит развивать.

Поскольку он более эффективен, чем реализация по умолчанию operator new, я бы сказал, что есть вероятность, что нет, он не будет более эффективным и вполне может быть менее эффективным. В основном вы указали, сколько стандартных библиотек было реализовано на заре C ++, но с тех пор многие (большинство?) Проделали большую работу над реализацией ::operator new, чтобы более точно адаптировать ее к динамическому распределению памяти. для использования в C ++ (где malloc в основном ориентирован на то, как он используется в C, который обычно, по крайней мере, немного отличается).

Что касается new[], то да, это просто изменение сигнатуры функции. Несмотря на то, что используются для однократного или множественного распределения, требования к operator new и оператору new [] `идентичны.

0 голосов
/ 18 ноября 2011

operator new отвечает за выделение базовой памяти объекта. Некоторые приложения используют схемы выделения, отличные от malloc, для выделения памяти. Одним из примеров является выделение пула. Приложение запрашивает большой объем памяти у операционной системы и управляет самой этой памятью. Это может защитить служебную информацию от системного вызова, предотвратить фрагментацию или предоставить временные гарантии для выделения памяти, что обычно не требуется операционной системе.

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

0 голосов
/ 18 ноября 2011

Если вы замените глобальный operator new, вам также следует заменить вариант nothrow. И, конечно же, глобальный оператор delete (как нормальный, так и вариант nothrow, потому что если конструктор объекта выдает, для nothrow operator new вызывается вариант nothrow operator delete).

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

...