Что касается размещения нового в C++

У меня проблема с размещением нового оператора. У меня есть две программы: Program1 (operator.cpp) и Program2 (main.cpp):

Программа1: operator.cpp

void *operator new(size_t size)
 {
   void *p;
   cout << "From normal new" << endl;
   p=malloc(size);
   return p;
 }
 void *operator new(size_t size, int *p) throw()
 {
    cout << "From placement new" << endl;
    return p;
 }

Вот вторая программа, к которой привязана первая: main.cpp:

     #include <new>
      int main()
      {
        int *ptr=new int;
        int *ptr1=new(ptr) int(10);
      }

Я индивидуально компилирую operator.cpp и main.cpp, как показано ниже:

operator.cpp: g++ -g -c -o operator operator.cpp

Затем связать его с main.cpp:

g++ -g -o target operator main.cpp.

Удивительно, но когда я выполняю ./target, он печатает: From normal new. Ожидаемый результат:

Из обычного нового Из размещения нового

Однако, если размещение new и main помещены в один и тот же файл, то вывод будет таким, как ожидалось:

Из обычного нового, Из размещения нового.


person RajSanpui    schedule 14.01.2011    source источник


Ответы (1)


В вашем [main.cpp] вы включаете <new>, который объявляет функцию

 void* operator new( size_t size, void* p) throw()

Вы не объявляете свою собственную функцию.

Следовательно, функция, объявленная new, является единственной известной и вызываемой.

Кстати, обратите внимание, что C++98 §18.4.1.3/1 запрещает замену функции, показанной выше (плюс три других, а именно формы одного объекта и массива new и delete с аргументом размещения void*).

Кроме того, пока я комментирую «кстати», есть вероятность, что какое бы новое размещение ни считалось решением, вероятно, существует более безопасное, столь же эффективное и более четкое решение более высокого уровня.

Ура и чт.,

person Cheers and hth. - Alf    schedule 14.01.2011
comment
Извините, но я с вами не согласен. Запрещает перегружать актуальное размещение new: voidoperator new(size_t size, void p). Но мы можем перегрузить void* в int* и перегрузить его. Я попробовал это в одном файле, и это сработало. Он показывает От размещения нового. Тогда почему при связывании того же самого с другим файлом его нет? - person RajSanpui; 14.01.2011
comment
@kingsmasher1 Я не согласен, может быть, вы неправильно интерпретируете функцию, показанную выше. Ответьте на вопрос в конце, потому что ваша функция не объявлена ​​в [main.cpp]. Просто заявите об этом. Ура и чт., - person Cheers and hth. - Alf; 14.01.2011
comment
@kingsmart: потому что, когда они у вас есть в отдельных файлах, вы НЕ перегружаетесь, так как в main.cpp нет перегруженного объявления - person Chris Dodd; 14.01.2011
comment
@kingsmart: я не могу объявить это в main.cpp, программа и моя проблема такова. У меня есть инструмент для отлова утечек памяти, и все перегрузки должны происходить отдельно, поэтому он объявлен отдельно в другом файле. Скажите, а как перегрузка нормального нового оператора работает в отдельном файле и дает результат нормально? - person RajSanpui; 14.01.2011
comment
@Alf.P: Если ваша идея состоит в том, что, поскольку я перегружаю в отдельный файл, поэтому он не работает, то это должно произойти и с другим обычным новым оператором. Тогда как это работает нормально, в другом файле? Я хочу, чтобы какое-то решение заставило его работать только из другого файла. Plesae, если вы можете предложить какое-то решение. - person RajSanpui; 14.01.2011
comment
@Alf.P: Просто намекаю на свою работу и почему я не могу объявить ее в main. Я работаю над инструментом утечки памяти. Идея заключается в том, что main.cpp — это пользовательская программа, которую нужно протестировать на наличие утечек. Когда в main.cpp появится новый файл, он должен перейти и попасть в новый файл operator.cpp, где я буду размещать некоторые счетчики и хэш-таблицы для отслеживания этой памяти. То же самое должно произойти и с размещением, так как новое размещение не имеет выделения памяти, поэтому, когда память используется новым размещением, это также должно быть добавлено в хэш-таблицу. А это может произойти только в том случае, если мы перегрузим размещение new. Спасибо, kingsmasher1 - person RajSanpui; 14.01.2011
comment
@ kingsmasher1: обычный новый оператор - это особый случай, чтобы поддерживать глобальную замену распределения C ++. однако для нового размещения вам необходимо объявление, которое будет видно на каждом сайте вызова. вы, скорее всего, поместите это в заголовочный файл, но подумайте, действительно ли необходимо размещение new: это настолько необычно, что, скорее всего, в этом нет необходимости. - person Cheers and hth. - Alf; 14.01.2011
comment
@Alf.P: Как мы можем поместить его в заголовочный файл Alf? Возьмем в качестве примера GDB. Можем ли мы сообщить пользователю, что если в вашем коде есть функция с именем foo(), вы добавите в свой код этот файл someheader.h? Конечный пользователь должен иметь возможность использовать инструмент как черный ящик, просто подключившись к моему инструменту, вызвав его и просмотрев журналы утечек. Так что, если вы можете придумать какую-нибудь идею, это действительно будет очень полезно для меня. - person RajSanpui; 14.01.2011
comment
@kingsmasher1, вы можете создать свою собственную версию нового файла заголовка и поручить пользователю добавить путь включения в заголовки вашего черного ящика. В этот новый новый файл вы можете включить исходный файл new (может помочь #include_next) и все необходимые дополнительные объявления. - person user396672; 14.01.2011
comment
@ user396672: Да, наконец-то я думаю, что мы должны это сделать. К сожалению, это показывает, насколько парализован этот C++ :-( - person RajSanpui; 14.01.2011