This blog post writes a dissertation about garbage collection, heap memory management, the absolute need to take courses on assembly language, and other contrived and absurd tangents.
Looking at the code, the guy gets a double-free because he instantiates two std::unique_ptr from the same raw pointer.
I'm sure the author felt very clever to pull up all these topics to write a blog post about, but in the end all they're doing is writing buggy code based on their misconception of a topic.
Yeah, unless I'm missing something the author would have the same outcome with regular pointers if he'd freed them at the same time (one at the end of the anon scope and one at the end of fun1). This is nothing to do with garbage collection and is simply a result of, as you mention, pointing to the same memory with two pointers and freeing both.
His issue seems to be with the implementation of malloc, which is pretty funny because he's basically claiming C itself has unpredictable garbage collection. I almost can't believe it's legit, it seems like such a basic, fundamental misunderstanding of concepts it's like chatGPT output.
Yeah, unless I’m missing something the author would have the same outcome with regular pointers if he’d freed them at the same time (one at the end of the anon scope and one at the end of fun1).
That's basically it. The way the blogger wrote fun1 means the pointer is freed once the function exits, because they explicitly added the std::unique_ptr to take over its lifetime. Afterwards they are surprised by the fact that it really took over its lifetime.
The weird part is that the blogger had to go way out of its way to write that bug.
I almost can’t believe it’s legit, it seems like such a basic, fundamental misunderstanding of concepts it’s like chatGPT output.
I agree. It almost sounds like one of those coding exercises recruiters throw candidates in preliminary hiring rounds to weed out the bottom 5% that have no idea what they are doing.
You can call it writing buggy code based on misconceptions, but the fact that it's possible (and not even especially difficult) to misuse smart pointers badly enough to produce program crashes and undefined behavior is still a fundamental weakness of C++ as a language.
As a counterexample, this type of bug is impossible to produce in Rust without explicitly using the unsafe keyword, and that keyword is something that is almost never used by regular developers and is an easy thing to audit for.
Edit: That being said, if you're stuck using C++ then obviously using smart pointers is the right thing to do whereas using raw pointers and managing the memory yourself is completely asinine, so if the author's point is to not use smart pointers in C++ then I suppose they want you to just... Leak memory? Because if you're able to figure out where it's safe to free a raw pointer, then you're able to figure out how to correctly use a smart pointer in that situation.
the fact that it’s possible (and not even especially difficult) to misuse smart pointers
Any tool can be misused, but there's a saying about those who blame the tools.
If you use a component designed to take over the ownership of an object but somehow make the mistake of assigning the same object to multiple components, the problem is not the language you're using. The problem is that you aren't paying attention to what you're doing.
I agree with what you're saying even though I do think a lot of C++'s bad rep comes either from C or from pre-C++11 code. I also think that modern code should include clang-tidy in the CI, and if so at least simple mistakes like in OPs code would be flagged with "warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]"
Note that all of the warnings in there are valid and should be fixed, so it's not like wading through a see of false positives. That being said, the post is interesting in its explanation of why the example does what it does. Too bad all of the other stuff in there is bonkers.
the fact that it's possible (and not even especially difficult) to misuse smart pointers badly enough to produce program crashes and undefined behavior is still a fundamental weakness of C++ as a language
I would argue it’s the natural state of C++. Crashes and UB lurk in every shadow, ready to pounce upon the unwary programmer.
It’s a powerful tool, but it’s not very forgiving.
It's maybe a weakness if you dont know what you're doing, the strength and power of C (and thus if you wish C++) lies in just that you can manipulate memory directly with just a raw pointer however dangerous it is.
I’ve been using unique_ptr since way before it was called that, and it’s not something magical. You need to know what it does and what it doesn’t or you’ll be surprised.
I always thought of unique as a warning not a guarantee. Make sure it’s the only thing pointing at your structure, or you’ll be in trouble.
You need to know what it does and what it doesn’t or you’ll be surprised.
I don't think that std::unique_ptr is shrouded in mystery: it's designed to be the unique handle of a raw pointer, and it frees the memory when it's lifetime ends. As it's designed to be the unique holder of a resource, it's implemented to disallow making copies. It might be implemented in clever ways, but a developer experience point of view it's quite straight to the point.
"They say C++ is specified in an international standard, but there is behavior that's left undefined. Are they lazy, or did their printer ran out of ink?"