What is C ++ reverse hell and why will it leak memory?

I watched the story of Herb Sutter CppCon 2016, in which he gave an example about 37 minutes in , something like this:

void f(shared_ptr<T> & ptr) { obj.on_draw([=]() { ... } } 

Then he says:

I heard that it’s called callback hell, where you register a callback and it has a strong owner - this is most likely a pointer to garbage collection but it is a strong owner, but then you will never get rid of it and it’s just stored there forever. and now the object will never disappear.

So, he says that he is called reverse hell, and he will flow objects. But I do not quite understand what happened to this code and why it will flow. Can anyone explain this to me?

I looked at other answers on stackoverflow, but they all look roughly concurrency.

+6
source share
1 answer

What Herb Sutter is talking about is circular links . It promotes a layered system where resources are not passed to code that "reaches"

Layer 1 - Owns resources and Objects from level 2 (and below)

Layer 2 - Cannot have strong references to level 1 objects

This ensures that the dependency graph does not get circles. Therefore, if level 1 frees all level 2 objects, all resources will be destroyed. Why this is important is pretty simple: counting resources from the C ++ Std library cannot deal with circular references (without counting references), if obj a has a strong link to obj b and obj b has a strong link to obj a, then they never will not be released.

The ugly truth is that this is also a problem if the circle goes through several links, possibly through software modules of different authors. Without a scheme like layers, you cannot just look at the code and say: "There is no chance that this will lead to a reference to the object that I am calling." Herb Sutter offers an agreement that if you do not know the implementation, you should never call a function that could support the resource.

This does not mean that you should never do this, but if you follow a set of rules, you can check the code for each layer or even for each file without knowing the rest of the system. Otherwise, you will need to find all possible paths that the function (on_draw) could follow to see if circular deviations can occur - and if something changes in any of the possible codes, then you need to do it again!

In this context, the “callback hell” is particularly problematic, as it wraps the type system (maybe it just doesn't allow interfaces from lower levels), and the callback can do something.

If the callback does not save the resource reference, use a simple pointer instead, this clearly indicates to the caller that he does not need to worry about leaks. Not now or in the future.

+5
source

Source: https://habr.com/ru/post/1011999/


All Articles