This post originated from an RSS feed registered with Agile Buzz
by Keith Ray.
Original Post: Bad APIs 2
Feed Title: MemoRanda
Feed URL: http://homepage.mac.com/1/homepage404ErrorPage.html
Feed Description: Keith Ray's notes to be remembered on agile software development, project management, oo programming, and other topics.
An alternative implementation of the function alloc(size_t size) could be defined to return a pointer to a block of memory that has the size at the front of it. In fact, this is how many implementations of these library functions are implemented -- but it wasn't standardized, and it wasn't made typesafe -- on those implementations where this was done, alloc would return a pointer to the data portion of the block, and you would have to "back up" and typecast the pointer to get the length portion of the block. A semi-typesafe example:
While this has the benefit of less space on the "client" side of the function (retaining one pointer instead of a struct with two fields) the danger of this style is that heap corruption is more likely - bad code writing past either end of the data field can erase those block_size fields.
Consider all the debugging tools we have today - would we need Purify, SmartHeap, and all those other tools as much if library functions like alloc and free had been implemented in a more object-oriented fashion?
I'm currently trying to debug some code (not written by me) that mixed C and C++ memory-management: it used "free" on memory allocated by "new char[]" and "delete []" on memory allocated by "alloc". I think these functions were smart enough not to work with memory that the other set of functions allocated, so there were memory leaks. In some implementations, these functions might be safely interchangeable for non-object allocations, in other implementations you can expect crashes.
So I fixed the code to be consistent, but I'm also getting crashes because some C++ objects are being deleted more than once [messing up the heap]. Apple's DebugMalloc provides some help in determining when the heap is messed up, but the irony is that DebugMalloc's leak detection feature works by implementing a form of garbage collection - it reports a leak when a memory allocation is no longer being pointed to. If I had real garbage collection, (or if the original coder had used boost::shared_ptr) I wouldn't have to worry about double-deletes.