-
Website
http://www.matasano.com/log -
Original page
http://www.matasano.com/log/663/taossa-on-novel-c-bug-class-deletedelete/ -
Subscribe
All Comments -
Community
-
Top Commenters
-
Press Controls
3 comments · 2 points
-
ChrisMtso
12 comments · 1 points
-
Eric Monti
11 comments · 1 points
-
StatlerAndWaldorf
12 comments · 3 points
-
Dave G.
7 comments · 1 points
-
-
Popular Threads
A few weeks ago it would have been C or C++ without a question. But with the prospect of hiring some new developers, I have to think about their knowledge as well. I can write safe C and C++ code, but can they?
AutoPtr foo = Create();
AutoArray fooArray = CreateArray(12);
When you're done with the pointers, these objects will release your allocations in the appropriate manner.
Using C++ without RAII resource management has always struck me as only driving your Porsche in first gear. You can get places, but it's a crying shame to see.
And yes, you'd be insane to consider C++ for a new project in 2007.
And about "arrays of THOSE objects" -- it's very easy, especially using STL vectors. Need an array? Here it is: vector array; Need an array of arrays? Nothing is easier: vector > array_of_arrays.
Second, you've misunderstood the whole point of the post. It's not that anyone's "discovered" delete/delete[]. You're right, it's a textbook example of a C++ coding mistake, and one everyone learns when they blunder into it in their first year of writing C++.
The point is, like a growing portion of C/C++ coding flaws, we are discovering ways to weaponize the flaw, turning it from a simple bug to an exploitable security flaw.
What I actually wanted to say is, you are right, "delete/[]" are harmful. And the rule is very simple -- don't use "delete/[]". Every time when starting to assess another project, start with grep'ing on "delete" and then "blame" in your favourite version control system. A good project should have no "delete" constructs anywhere, except maybe one or two well tested and documented places.
And if the project does not have any "delete" left, there shouldn't be any problem with them anymore?
After we have answered the first part of the question, "what to do?", there's a second part which sounds "how?", and "vectors and RAII" is the answer.
I don't buy that you can evict delete with RAII.
In any nontrivial project, a sizeable portion of all your objects won't be block-scoped.
there are, generally speaking, three types of objects:
1. small objects which are block scoped
2. not-so-small objects which are block scoped
3. other long-living objects
Objects of the first kind could be easily created on stack without new/delete hassle and even without any RAII -- they will be automatically destroyed when the block ends.
Objects of the second kind usually cannot be allocated on stack because of their size, so we need some kind of RAII wrapper, which frees the memory when object goes out of scope.
Third kind of objects is the most interesting, but still very simple to deal with. Object definition/declaration should be wrapped in auto_ptr (or shared_ptr or any ptr wrapper of your choice), and delete is either simply removed or replaced with trivial sink() construct if you prefer to release memory immediately and don't want to wait until the program termination.
Actually, I sometimes do a lot of bugfixing in someone else's code. And beforementioned steps are the first I do to deal with incorrect exception handling and/or memory leaks. Works like charm =)
1. Block scoped objects
2. Not block scoped objects
The "not block scoped" case is the majority of all objects in nontrivial code.
You've now introduced shared_ptr as a means of eradicating delete calls for that case. But shared_ptr has its own dangers. C++ libraries, including some of the standard libraries, aren't
designed to retain shared_ptrs with type intact. The moment you alias a shared_ptr to a naked pointer, you've introduced another, scarier class of bugs.