与覆盖全局新建和删除运算符有关的问题

Problems related to overriding global new and delete operators

本文关键字:问题 运算符 删除 覆盖 全局 新建      更新时间:2023-10-16

不久前,我看到一篇关于全局覆盖新运算符和删除运算符的问题的帖子。Post表示,这可能会导致STL和许多其他库出现问题。

现在我正在写一个内存管理器。我正在考虑覆盖全局新建和删除运算符,以优化整个应用程序。在自定义内存管理器中,使用了相同的新旧运算符和删除运算符(在运行时根据需要分配大块内存,同时分配部分内存供我的软件实际使用)。

  • 我对这种方法有什么问题吗?我希望在我的应用程序中使用许多库,如DirectX、STL和Boost
  • 我在第一段提到的那些谣言是真的吗

我正在使用VS2010

--编辑--

我应该在MemoryManager程序中使用malloc()和free()。

如果要覆盖全局新建/删除,最好使用经过良好测试和性能良好的库:

  • TCMalloc
  • NedMoloc

原因是这些库在一般情况下会比你能写的任何东西都好(更少的bug,更高的性能等)。如果您需要为非常特定的情况(堆栈分配、池)进行特定的分配,则必须使用用户可以更改的自定义分配器使代码可扩展(如果用户可以访问和重新编译源代码,则很容易,否则您必须提供某种接口)。

请注意,STL容器使用自定义分配器,因此您可以通过更改分配器来提高/降级它们的性能:

C++11方式:

namespace myspace{
    template< typename T>
    using myVector = std::vector<T, yourAllocator<T>>;
}
//usage
myspace::myVector vec;

旧方法:

namespace myspace{
    template<typename T>
    struct myVector{
        typedef std::vector<T, yourAllocator<T>> type;
    };
}
//usage
myspace::myVector::type vec;

如果你真的想覆盖全局new/delete,你所需要的就是编译你自己版本的new/delete(当然你必须使用一些malloc/malloc库),并将其作为最后一个链接到你的可执行文件中(我认为顺序无关紧要,除非其他人也覆盖了这些运算符)。

问题:

在Windows上,无法覆盖无法控制链接的DLL的全局新建/删除返回并重新阅读。如果无法重新编译/重新链接DLL,则无法覆盖其内存分配,这意味着在使用DLL时必须小心。一般来说,这不是问题,除非你试图用自己的删除删除DLL创建的东西。对于没有问题的系统DLL(您可以仅使用系统函数创建对象/句柄,也可以仅使用体系函数销毁对象/句柄)

我只是问你一个问题,我会让你找到答案:如果你有一个类,该类被编译成DLL(在Windows上),如果你用自定义的new/delete创建了一个子类,然后创建了该类的自定义实例,你真的需要担心吗?

class DLLEXPORT AClass{
//stuff
//...
};

您的代码

class MyClass: public AClass{
};

class MyClass: public virtual AClass{
};

//inside your program
AClass * a = new AClass;
MyClass * m = new MyClass;