16 June 2004

Memory management

Trudging through the recent Joel post and read this little gem:

The biggest advantage of .NET is the fact that it has automatic memory management.
If your programming language allows you to grab a chunk of memory without thinking about how it's going to be released when you're done with it, you're using a managed-memory language, and you are going to be much more efficient than someone using a language in which you have to explicitly manage memory.

People often complain about memory management in C++. Although it's true that you have to consider memory management, a couple of simple, well-known techniques push it in the background. They are sometimes even better than the garbage collection in managed languages.

Joel has several complaints (although the article is not primarily about memory management). He says that a programmer can be more productive in VB because of its memory management. His examples seem to cover C API limitations:

Typically, you have to call the function twice—on the first call, you tell it that you've allocated zero bytes, and it fails with a "not enough memory allocated" message and conveniently also tells you how much memory you need to allocate.

These situations usually have been (or easily can be) buried in object oriented code so that you can ignore it as easily as in a managed language. Although that burying has to be written, the code is so limited and simple that it would add very little to a project schedule. Also, if you're writing code to wrap an API, it is going to be reused and will simplify every instance of calling that API.

This solution resolves a very specific C API model. The more common complaint is with new-ed memory which is solved by never new-ing memory outside of a smart pointer. If a class must defer creation of a member variable, use auto_ptr. If you must pass memory and lose ownership, use auto_ptr. With it, you control allocation and understand deallocation. Much better than the lazy garbage collection in managed languages.

Joel gives three points on why memory management is better:


  1. Functions can return complex data types,

  2. Developers don't have to write code to free data or debug memory leaks,

  3. Developers don't have to coordinate function exit points to free data

Smart pointers take care of all of those. Most are free in the standard, others are easily available or easy to create.

If the biggest advantage of .NET is automatic memory management, why is it so easy to resolve this without .NET?

Here's another simple method to eliminate memory management concerns: use std::vector<unsigned char> as a generic memory buffer. Scott Meyers reccommends this in Item 13 from Effective STL. This is even simpler than using auto_ptr with new, but should only be used when dealing with raw memory buffers and not with C++ objects:
// Begin with a buffer of bytes.
size_t dataSize = 1024;
std::vector<unsigned char> dataVec(dataSize);

// Call the legacy function and enlarge the buffer until it returns non-zero.
while (::legacy_cfunc(&dataVec[0], dataSize) == 0)
{
dataSize += 1024;
dataVec.resize(dataSize);
}
[ posted by sstrader on 16 June 2004 at 1:34:10 PM in Programming ]