Как сделать так, чтобы мои зависимости называли мой глобальный оператор новым? - PullRequest
4 голосов
/ 31 октября 2010

У меня есть тестовое приложение, которое связано с некоторыми DLL (или .so). В моем основном приложении я определил глобальный новый / удалить как это:

void* operator new(size_t n)
{
    ....
}

void operator delete(void* p)
{
    ...
}

Но я заметил, что операторы вызываются только для тех вещей, которые я выделяю в моем основном приложении, но не для одной из библиотек DLL.

Как сделать так, чтобы выделения в DLL проходили через мой оператор new / delete? (Это также должно включать память, выделенную STL, поэтому, если в одной из DLL есть std :: string, я бы хотел, чтобы мой оператор new вызывался, когда STL выделяет свой внутренний буфер std :: string).

Меня больше интересует решение для Windows, но также будет полезно и решение для Linux.

edit: возможно, я изначально не был понятен, это тестовое приложение, которое я делал, предназначалось для отслеживания использования памяти для нескольких автоматически сгенерированных классов, определенных в DLL. Создать свой собственный распределитель и использовать его в сгенерированном коде структуры STL не вариант, более того, есть и другие не-STL распределения. Но, увидев ответы, я думаю, что лучше всего использовать профилировщик или просто отслеживать использование памяти с помощью perfmon.

Ответы [ 3 ]

2 голосов
/ 31 октября 2010

Я бы хотел, чтобы мой оператор new вызывался, когда STL выделяет свой внутренний буфер std :: string

typedef std::basic_string<char, std::char_traits<char>, ALLOCATOR> mystring;

Код в DLL ужеиспользует собственную реализацию new, и нет веской причины, по которой определение вашей собственной реализации должно волшебным образом изменить реализацию, которую используют библиотеки DLL (что, если они используют свою собственную пользовательскую реализацию?).

Так что если вы хотитеСтроки для использования вашего распределителя, вам нужно явно создать их как таковые.

1 голос
/ 31 октября 2010

Нет способа полностью сделать то, что вы хотите сделать.Слишком много угловых случаев утечки памяти.

Самое близкое, что я думаю, вы можете получить, выполнив следующее: Каждый класс в вашей dll / .so должен иметь статический метод factory / destroy.Передайте указатель на функцию выделения на фабрику, а функцию освобождения - на метод уничтожения в каждом классе в каждой dll / .so.

. Пример того, как приблизиться, в Google для библиотеки выделения памяти HORDE., что очень близко.

Еще одна вещь, на которую стоит обратить внимание, это различные библиотеки плагинов класса C ++, которые позволяют загружать любые dll / .so как плагин.В прошлый раз, когда я проверял, в гуглсфере было как минимум 10 таких библиотек с источником.:)

1 голос
/ 31 октября 2010

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

Если вам действительно нужно это сделать, вам придется перехватывать вызовы malloc (и другой процедуры выделения).Это не легкоВы не можете просто сделать это из кода.Вы должны будете сказать компоновщику, как это сделать.В Linux я думаю, что это LD_PRELOAD, хотя я не могу вспомнить, а в Windows я совсем не уверен.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...