如何让我的依赖项调用我的全局运算符new?

时间:2010-10-31 07:08:51

标签: c++ windows linux memory

我有一个与某些DLL(或.so)链接的测试应用程序。在我的主应用程序中,我定义了一个像这样的全局新/删除:

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

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

但是我注意到操作符只调用我在主应用程序中分配的内容,但是如果其中一个DLL没有调用它。

如何在DLL中进行分配通过我的运算符new / delete? (这也应该包括由STL分配的内存,所以如果其中一个DLL有一个std :: string,我希望在STL分配其std :: string内部缓冲区时调用new operator)。

我对Windows解决方案更感兴趣,但Linux也会受到赞赏。

编辑:也许我最初并不清楚,我正在做的这个测试应用程序是为了跟踪DLL中定义的一些自动生成的类的内存使用情况。创建我自己的分配器并在生成的代码STL结构中使用它不是一个选项,更是如此,还有其他非STL分配。但是看到答案,我认为最好的选择是使用分析器或者只是使用perfmon监视内存使用情况。

3 个答案:

答案 0 :(得分:2)

  

当STL分配其std :: string内部缓冲区

时,我希望调用new operator new

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

DLL中的代码已经使用了自己的new实现,并且没有充分的理由为什么定义自己的实现应该神奇地改变DLL使用的实现(如果他们使用自己的自定义实现怎么办?)。

因此,如果您希望字符串使用您的分配器,则需要明确地创建它们。

答案 1 :(得分:1)

任何旨在使用全局定义的内容都必须使用可用的定义进行编译。您使用的技术不会覆盖已在DLL中编译的任何内容,甚至不包括不包含这些定义的其他源文件。在许多情况下,即使可见,分配器和标准功能也不会使用这些功能。

如果你真的需要这样做,你将不得不拦截对malloc(和其他分配例程)的调用。这并不容易。你不能简单地从代码中做到这一点。您必须告诉链接器如何执行此操作。在Linux上我认为这是LD_PRELOAD,虽然我不记得了,在Windows上我根本不确定。

如果您可以说明您为什么要这样做,也许我可以提供替代解决方案。

答案 2 :(得分:1)

没有办法完全做你想做的事。有太多内存泄漏的极端情况。

我认为你能得到的最接近的是: 你的dll / .so中的每个类都必须有一个静态的工厂/销毁方法。将指向分配函数的指针传递给工厂,并将解除分配函数传递给每个dll / .so中每个类的destroy方法。

关于如何关闭的示例,谷歌搜索HORDE内存分配库,它确实关闭了。

另一件需要关注的是各种C ++类插件库,它们允许您将任何dll / .so作为插件加载。上次我检查了googlesphere中至少有10个这样的源库。 :)

相关问题