Я не программировал C++ некоторое время и столкнулся с странным поведением при работе с перегруженными глобальными операторами new
и delete
. Суть проблемы заключается в том, что оболочка построена вокруг глобального new
и находится в отдельном исходном файле , тем не менее, вызывает operator new
, перегруженный в другом (и отдельно скомпилированном) исходном файле.Рекурсивные вызовы при попытке обернуть и переопределить глобальный оператор new
Почему это так, т.е. какие языковые правила/функции я нарушаю/неправильно использую?
Заранее благодарим за детали.
Структура проекта:
.
..
main.cpp
mem_wrappers.h
mem_wrappers.cpp
файлы проекта Содержание:
main.cpp
#include "./mem_wrappers.h"
#include <iostream>
#include <cstring>
void* operator new[] (size_t sz) throw (std::bad_alloc) {
std::cout << "overloaded new()[]" << std::endl;
return default_arr_new_wrapper(sz);
}
int main() {
const unsigned num = 5;
int * i_arr = new int [num];
return 0;
}
mem_wrappers.h
#include <cstring>
void * default_arr_new_wrapper(size_t sz);
mem_wrappers.cpp
#include <new>
#include <cstring>
#include <iostream>
void * default_arr_new_wrapper(size_t sz) {
std::cout << "default_arr_new wrapper()" << std::endl;
return ::operator new[](sz);
}
Соблюден г ++ main.cpp mem_wrappers.cpp параметр --ansi --pedantic -Wall при запуске дает бесконечное operator new[]
к default_arr_new_wrapper
и наоборот вызовы приводит к следующему выходу :
overloaded new()[]
default_arr_new_wrapper()
overloaded new()[]
default_arr_new_wrapper()
...
и, наконец, в SO (компилятор MS Visual Studio Express ведет себя одинаково).
Составители я использую: GCC версии 3.4.2 (MinGW-специальное) и MS Visual Studio 2008 Версия 9.0.30729.1 SP.
EDIT/UPDATE
Если (как первые ответы и комментарии предполагают) глобальный operator new
эффективно переопределен для всего исполняемого файла просто перегружать его [оператор] в одном модуле компиляции, то:
это просто связывание с объектным файлом, источник которого перегружает глобальный operator new
, заставляет ли какое-либо приложение или библиотеку изменять свою политику распределения памяти (ну, так называете ее)? Таким образом, этот оператор перегрузки эффективно обеспечивает крючок для языковой среды выполнения (я имею в виду то, что с этими символами компоновщика в уже скомпилированных без каких-либо перегруженных новых объектных файлах, заключается в том, что может быть только один new
)?
P.S. Я знаю, что malloc
и free
сделали бы, и уже пробовали их перед публикацией здесь (работала нормально), но тем не менее, что стоит за этим поведением (и что, если бы я на самом деле обертывал по умолчанию operator new
? :))?
Как следует из названия, глобальный оператор новое носит глобальный характер. – 2009-12-13 16:43:24
@Neil А как насчет связи (разве это не глобально для текущего блока компиляции)? – mlvljr
mlvljr, вы можете поместить \ (обратная косая черта) перед вашими подчеркиваниями, чтобы избежать выделения курсивом следующих символов. Но в целом, когда вы ссылаетесь на имя переменной, предпочтительнее отображать ее как код, например 'varname'. –