Garbage Collection and Pointers

| 5 Comments | 1 TrackBack
So, Richard Hale Shaw is helping us move away from C++ and in his latest posting on the subject he explains how "veteran C++ programmers" don't like to manage memory themselves; hmm. I'd quite like to see his sample data. Especially as he then goes on to define "veteran C++ programmers" as people who don't like to manage memory themselves...

"But veteran C++ developers testify that - without taking special precautions - you'll invariably introduce more programming errors by managing memory yourself:
· Using a pointer without initializing it first
· Forgetting to set a deleted pointer to NULL
· Forgetting that a deleted pointer has been deleted (and trying to use it), and
· Forgetting to delete an initialized pointer, etc.

Indeed, a good gauge for whether someone is a veteran C++ programmer is to ask if they think they can manually manage memory better than a program written to do so can."

I guess 14 years of C++ doesn't make me a veteran, unless everything I'm about to say can be dismissed as 'special precautions'...

Personally, I don't have a problem with memory management. I've reviewed a lot of code that does have problems with memory management but then that same code also tends to have problems with most other aspects of programming; I've never seen well designed, clean code that only has memory management problems. It seems to me that a C++ program with lots of memory management issues is likely to have lots of other issues as well and the memory leaks are just the most visible and/or destructive of the problems. Memory is only one of the many resources that need to be managed in a program and if you're unable to get your head around memory management then you're unlikely to understand how to manage files, or sockets or database connections or event handles or critical sections... Programming well requires the ability to focus on details; being unable to manage memory implies a lack of ability to focus on detail. Removing explicit memory management may remove the potential for problems for those who consistently get it wrong but it doesn't help them to write better code, or to manage other resources. Richard's issues above seem to me to be symptoms of a lack of attention to detail. What's more, surely the first issue "using a pointer without initialising it" is just as much as an issue with object references; use of a null object reference will generate an exception. The second and third issues are not memory management issues but program design issues. Which leaves us with "forgetting to delete an initialised pointer" for which those of us working with C++ came up with a reliable solution long ago in the form of the "Resource Acquision Is Initialisation" (RAII) idiom. What's more, RAII solves the general problem of resource leaks rather than the specific problem of memory leaks; it's akin to .Net's IDisposable pattern only cleaner ;).

Richard continues with the merits of the .Net way:
"The new operator returns an object reference - but one that can't be de-referenced - and not a pointer per se." ... "except de-reference them or point them at arbitrary addresses"

It's a pointer Jim, but not as we know it. Given that an object reference can be null the fact that you can't 'de-reference' it explicitly seems to irrelevant. The object reference can be null at the point of use and if you don't "know" that it can't be null in a particular situation, or explicitly test the reference for null before attempting to use it then an exception will be generated. Likewise in .Net you can cast an object reference to a reference to another type. Admittedly the casting will try and stop you from doing the wrong thing, but you can "work around" that by casting to Object first. C++ casts offer the same level of protection and if you're a C++ programmer using 'C style casts' then your code has more problems than just memory management issues. So, it seems to me, that Richard's .Net object reference advantages boil down to one thing, you can't use an unassigned, "dangling", object reference; such an attempt is a compiler error whereas in C++ it would merely be a warning...

"C# and .NET reduce the number of program errors you can introduce"

I agree. Since C# and .Net are simpler and more constrained than C++ it would be difficult for it to be any other way. You can do some very nasty things in C++ but you generally don't need to do these things and if you are doing them then it's usually a symptom of a bigger problem.

Programming well in any language or environment requires the ability to focus on details and knowledge of the idioms and techniques appropriate for that language or environment. The advantage of C# and .Net over C++ is not that it has garbage collection and you can't de-reference pointers, it's that for certain kinds of applications C# and .Net provide all the functionality that you need. It means your programmers don't need to be able to deal with as much complexity as they would if they were working in C++. This probably means that you can find more people who are competent enough to be able to write your application.

1 TrackBack

C++ & Memory Management from HMK's Spurious Thoughts on August 27, 2005 9:29 PM

Len Holgate has an excellent post on C++ & memory management (although the following citation sounds quite harsh, there are lots of insightful thoughts in his post): Memory is only one of the many resources that need to be managed... Read More

5 Comments

I'm not one to flame people but RHS has gone totally insane. I am too a consultant and I can't tell you how many projects I have seen that were written in .NET and had to be completely re-written due to performance issues. I'm not saying that .NET can't perform, the real issue IMHO is the barrier to entry has gone down with .NET. A lot of .NET devs just don't seem to have a clue how to design software. Ok, I'm done bitching.

I was hoping that the series would be reasonable well balanced but it looks like he's just going to take the rather predictable C++ bashing route.

I agree that there's a problem with lowering the barrier to entry; there always is. The upside of that is that often skilled people can produce good software much faster. The downside is that unskilled people can also produce software faster, it just tends not to be good.

> Personally, I don't have a problem with memory management. I've reviewed a lot of code that does have problems with memory management but then that same code also tends to have problems with most other aspects of programming; I've never seen well designed, clean code that only has memory management problems.

This is an incredibly specious argument considering the number of buffer overrun exploits-- the archetypal memory management error-- in Linux, Windows, and every other system written in C or C++.

As long as human beings are writing the code, it WILL have buffer overrun exploits in it somewhere. The only workable solution is to remove the people from the equation via the .NET runtime, eg, convert unmanaged C++ to managed C++.

Jeff, I agree completely with the problem (human beings aren't good at repetetive tasks, like checking arguments to strcpy()) and I think len does too. The conclusion is off though.

Just because C/C++ come with interfaces that require lots of manual checking by humans doesn't mean those are the ones you have to use (see: http://www.and.org/vstr/security ). Using interfaces that help programers do the right thing, is good.

Also "buffer overflows" as an attack _are_ declining (and have system level protections like exec-shield and address randomised binaries) while problems due to XSS/privilage escalation/etc. are on the rise ... what do these things have in common?
While someone has designed entire new languages with a basic String type so the "let's malloc+strcpy and hope for the best" crowd can't be complete muppets, no one has yet done that for XSS -- and obviously, the people using the "safe" languages are still defining bad interfaces that require the humans to check something repeatedly.

Jeff

Firstly, thanks for making me look up specious ;)

As James says, just because there are some unsafe functions available it doesn't mean that you have to (or should) use them. Switching languages or development environments to avoid these unsafe functions is one solution but it's not the only solution. In some situations it's not appropriate to move to .Net or Java. Just because you need to work in C or C++, you don't need to use unsafe functions that can make buffer overflows possible...

The new 'safe CRT' with VS 2005 is a step in the right direction, especially as the compiler can warn you if you're using 'deprecated', unsafe, functions. That this comes with the compiler that many windows developers will be using in the near future is a good thing; though, of course, some may turn off or ignore warnings...

The main point I'm making here is that if you can manage your other resources you can usually manage your memory. Failure to manage other resources well isn't usually as obvious as failure to manage memory well. Memory problems are a good indicator that a project is in trouble and that the developers have wider resource management issues...

Leave a comment