Почему мой новый оператор не называют

Ручной останов программы - эффективный, проверенный способ найти проблемы с производительностью.

правдоподобным? Не для большинства. Правда? Совершенно верно.

Программисты гораздо более осуждающие, чем необходимо.

Свидетельствуйте все, что считается «злым» или «ужасным» на этих постах.

Программисты довольны структурой данных.

Засвидетельствуйте все обсуждения классов, наследования, private-vs-public, управления памятью и т. Д. Против того, как анализировать требования.

8
задан phlipsy 30 June 2009 в 17:26
поделиться

4 ответа

Проблема в том, что на большинстве платформ UNIX (в отличие от Win32 и AIX ) все ссылки на символы по умолчанию привязаны к первое определение символа, видимого загрузчику среды выполнения.

Если вы определите 'operator new' в основном a.out , все будет привязано к этому определению (как показывает пример Нила Баттерворта), потому что a.out - это самый первый поисковый загрузчик времени выполнения образа.

Если вы определяете его в библиотеке, которая загружается после libC.so (или libstdc ++. Поэтому в случае, если вы используете GCC ), ваше определение никогда не будет использоваться. Поскольку вы dlopen () загружаете свою библиотеку после запуска программы, libC уже загружена к этому моменту, и ваша библиотека будет последней, которую загрузчик времени выполнения будет искать; так вы проиграете.

На платформах ELF вы можете изменить поведение по умолчанию, используя -Bsymbolic . Из man ld в Linux:

 -Bsymbolic
   When creating a shared library, bind references to global symbols
   to the definition within the shared library, if any. Normally, it
   is possible for a program linked against a shared library to override
   the  definition within the shared library. This option is only meaningful
   on ELF platforms which support shared libraries.

Обратите внимание, что -Bsymbolic - это флаг компоновщика, а не флаг компилятора. При использовании g ++ вы должны передать этот флаг компоновщику следующим образом:

  g++ -fPIC -shared library.cpp -o library.so -Wl,-Bsymbolic
11
ответ дан 5 December 2019 в 13:01
поделиться

Следующий код работает должным образом. Ожидаете ли вы, что код вашей динамической библиотеки будет использовать предоставленные вами new / delete? Я думаю, вы будете разочарованы.

#include <memory>
#include <cstdio>
#include <cstdlib>
using namespace std;;

void* operator new(size_t size) {
        std::printf("New...\n");
        void *p=std::malloc(size); 
        if (p == 0) // did malloc succeed?
                throw std::bad_alloc(); // ANSI/ISO compliant behavior
        return p;
}

void operator delete(void* p) {
        std::printf("Delete...\n");
        std::free(p);
}

int main() {
    int * p = new int(42);
    delete p;
}
1
ответ дан 5 December 2019 в 13:01
поделиться

Я думаю, проблема в том, что перегрузка операторов в C ++ является функцией времени компиляции, а не времени компоновки. Библиотека DLL была скомпилирована без информации о перегруженном new (), поэтому она не будет работать правильно.

Другая возможность состоит в том, что на вашей платформе она будет работать с использованием связывания (как в вашем примере), но DLL не разрешает символы из вашего исполняемого файла.

0
ответ дан 5 December 2019 в 13:01
поделиться

Загляните в RTLD_DEEPBIND

1
ответ дан 5 December 2019 в 13:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: