New and delete operators override in libraries
Asked Answered
I

2

18

What happens if two libraries (dynamicaly linked) have their own globally overridden version of the new and the delete operators and they use their own memory management?

Is it generally wrong to ship memory management facilities inside a library, or can it be good in some cases to provide memory management only for some specific classes, defining only class-specific new and delete operators override?

Are there some differences in the case of static linked libraries?

Imbibe answered 11/12, 2015 at 13:6 Comment(4)
You have a specific use-case? new and delete can be overridden, but what for? Or is that a theoretical question (which would be for pretty advanced users and uses I think)?Anaphylaxis
Dynamically linked libraries don't exist as far as standard C++ is concerned, so your question is platform-specific. Are you interested in a specific platform?Crony
@SebastianRedl unix related, .soImbibe
@Elyasin use-case: memory pool implementationImbibe
Y
9

In general, this is labelled "here be dragons". It depends on all sorts of things. Often the two libraries will fight, and new and delete will end up overridden by one of them - that's the best you can hope for.

Alternatives:

  • Library A starts up. Overrides new/delete, allocates some memory. Library B starts up and overrides. At system shutdown, library A's memory is freed with library B's delete. That is not good.

  • Memory allocated in library A uses library A's override, and similarly for library B. If you ever end up with memory allocated in library A being freed by library B, you will lose. (And it can be even more confusing, because if the object being deleted by B has a virtual destructor, the deletion can end up being done by A ... so it works.)

Yentai answered 11/12, 2015 at 13:16 Comment(0)
U
8

I think Martin pretty well answers your question, by outlining what happens and also nothing that it's a bit dangerous and not highly advisable (there be dragons indeed). Let me extend it a bit by providing an alternative: avoid overriding new/delete, and instead use the allocator concept.

For instance, if you look at std::vector, you notice that it is templated both on what type it stores, but also on an allocator. By writing a conforming allocator, you can control exactly how std::vector allocates and de-allocates memory. Notice how nice and loosely coupled this is: you have no difficulty exerting full control over memory allocation even though you can't change any of the original std::vector source code.

If you want library B to do allocation in a specific way, what I would do is:

  1. Write an allocator that conforms to the allocator concept in the way that std::allocator does.
  2. Make sure that all classes that use dynamic memory allocation directly (e.g. not through one of their members) are allocator aware.
  3. Typedef all of those classes so that they use your allocator by default.

To clarify step 3, what I mean is write something like this in a fundamental header file of your library:

template <class T>
using my_lib::vector = std::vector<T, my_lib::MyAllocator<T>>;

Now you can use ''vector'' anywhere in your library, which will be a normal vector but using your allocation scheme.

Step 1 can range from very easy (for stateless allocators) to quite tricky (there's a number of gotcha with stateful allocators). As for step 2, it's quite straightforward as far as dynamic memory for containers goes as all of the containers in the standard library already support this. But if you are using dynamic memory for e.g. polymorphism, you'll need to do a bit of extra work (probably write a suitable wrapper) to do this in an allocator-aware way.

If someone has good examples of reasons why you'd want to override new/delete as opposed to using allocators (e.g. because there is something you can't do with allocators) I'd be interested to hear them.

Edit: and just to bring this full circle, note that there will not be any problem using libraries A and B simultaneously if you do this, as no global operators have been overridden.

Uam answered 11/12, 2015 at 13:54 Comment(3)
I had thought "here be dragons" was clear enough to mean "don't do that", but +1 for suggesting a good alternative.Yentai
@MartinBonner You're right, I slightly misread the question/answer. Let me change the wording a bit, didn't mean to sell your very good answer short.Uam
this is only possible if you make both libraries. If you are using third party library you have to rewrite it like an idiotAllstar

© 2022 - 2024 — McMap. All rights reserved.