a library forces global overloads of new/delete on me!

微笑、不失礼 提交于 2019-11-29 07:41:32

If you're compiling in (via header inclusion) an overridden new/delete operator(s), then all calls in your code to new/delete will use them. There is no way to re-override it (link errors) or only partially override it, etc.

It is bad form to override the global new/delete operators, at all. It's a bad idea. If you don't realize why it's a bad idea, you're not qualified to do so. If you do realize why it's a bad idea, you're qualified to do so, but you'll generally choose not to.

Defining a global new/delete is exponentially more evil in a component you expect people to include directly into their project. It is your job as a customer to help the vendor doing this understand the seriousness of the situation, or stop being their customer.

You can define a custom allocator type (see this link for a good tutorial on how to do so, the interface needed, etc) and use that exclusively with your STL types (it's a template argument).

For shared_ptr, you need to do something a little different: it takes a deleter object as a parameter to the constructor if you don't want the default "delete p" behavior. This isn't a custom allocator; it's just a regular unary functor.

Isn't it possible to do this:

namespace evil{

#include "evil_header.h"

}

Then what evil_header declares as global new/delete becomes evil::new/evil::delete. I doubt this will play well if there are non-header definitions of things declared in evil_header though.

You can use another new in your namespace:

namespace MyNS {
    // Declare your new/delete operators here
    // and also declare a class implementing the same interface as std::allocator
    // using your newly created memory management functions.
    // Don't forget to put all your classes in the namespace.
    // (if you don't have one already)
}

Your can then use all STL classes, giving them your allocator type as template argument.

One option is to create your own overloaded new operator that can be implemented in terms of malloc.

This could be defined like:

enum MyNew {EMyNew};

void *operator new(size_t size, MyNew);

This can then be called by you as MyClass* myClass = new (EMyNew)MyClass;

Since this is implemented in terms of malloc, it should behave as expected. The only downer is that you will have to replace all the instances of where you have used new.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!