Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

My Favorite C++ 10-Liner

Download

Right click “Save as…”

Slides (view online)

I’ll share my favorite 10-line piece of C++ code I’ve come across and explain just how amazingly much it does in those 10 lines. And, if that doesn’t fill 20 minutes, I might just share more than one 10-liner…

 

Follow the Discussion

  • winrtwinrt

    thank you ms

  • Michi HenningMichi Henning

    The cache example is very slick and elegant. But it does have a problem: the cache grows without bound. Even after all shared_ptrs to an entry in the cache have been dropped, the cache map itself keeps hanging onto a weak_ptr for the now-dead entry. This can be a problem for long-lived programs if the key space for the map is sparse and unpredictable, and if entries frequently come and go.

    I'm not sure whether there is a good solution for this. The best I can think of is to allow a reaping pass to be made over the map once it grows beyond a certain size, and to throw out any weak_ptrs whose lock() call fails. Unfortunately, that takes O(n) time and, if most of the entries in the map are indeed still in use, the pass won't reclaim much.

    It seems this approach is useful mainly in situations where, once a widget is created, it tends to hang around until the process dies.

  • Michi HenningMichi Henning

    Thinking about this some more, another way to solve the problem would be to store a handle (weak_ptr or even raw pointer) to the factory in each widget and, in the widget destructor, use that to go back to the cache and remove the entry for that widget from the cache. But it doesn't look like that's possible with the interfaces as shown (because load_widget doesn't know the address of the cache and, therefore, can't pass it through to the widget constructor).

    Michi.

  • PeteMPeteM

    Thank you everybody who made this possible. I hope you guys keep this up year after year.

  • Jon HarropJon Harrop

    @Herb: You describe your 10-liner as "a thread-safe reference-counted object cache". The common name is a concurrent weak dictionary. In particular, one with weak values (rather than keys). As Michi has pointed out, your implementation contains a memory management bug that is difficult to fix in C++. In contrast, you will find that reliable concurrent weak dictionaries are widely available for C#, F# and Java.

    @Michi Henning: What you describe as a "reaping pass" is actually a garbage collector. So you are suggesting that Herb fix the memory leak in his favorite C++ code by adding a garbage collector to it. Let me be the first person to agree with you! Better yet, stop using C++ and use something that bundles a GC...

  • @Jon Harrop:

    @Michi Henning: What you describe as a "reaping pass" is actually a garbage collector. So you are suggesting that Herb fix the memory leak in his favorite C++ code by adding a garbage collector to it. Let me be the first person to agree with you! Better yet, stop using C++ and use something that bundles a GC...

    Why this pathological focus on garbage collection (of memory)? It misses the broader point.

    Memory management is just a special case of the more general problem – resource management! Your classic garbage collector does *not* solve that problem.

    Python (a garbage collected language) have the same issues:

    >>> fp = open (filename, 'rb')
    >>> msg.attach (MIMEImage(fp.read())) # might throw!
    >>> fp.close()

    (WTF! Why doesn't the code-block preserve my linebreaks!?!)


    If an exception is thrown you have no guarantees on when the file handle will be closed/released. And you might start leaking resources.

    Modern C++ have come a long way at solving the resource management problem. Listen to Bjarne Stroustrup excelent talk. He explains it way better than I am able to. Sean Parent's talk "Inheritance Is The Base Class of Evil" is also highly recommended!

    C++ is a complex and hard to learn language; so it's not for everyone. And there are lots of god reasons not to use C++ at a particular project. But general statements like "stop using C++ and use something that bundles a GC", is just plain wrong! (IMHO)

    And you can of course just plug a garbage collector into your C++ program. Like the open source vector drawing program Inkscape does.

  • WillWill

    @torbjo Some GC languages have introduced a "dispose pattern" ( http://en.wikipedia.org/wiki/Dispose_pattern ); e.g. your Python example becomes (sorry I can't format code):

    >>> with open (filename, 'rb') as fp:
    >>> ... msg.attach (MIMEImage(fp.read()))
    >>> # no explicit fp.close()

    But I strongly agree with all the rest of your post!

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.