Here we are! We spent 4 articles explaining what memory is, how to deal with it and what are the kind of problems you can expect from it. Even the best developers write bugs. A commonly accepted estimation seems to be around of few tens of bugs per thousand of lines of code, which is definitely quite huge. As a consequence, even if you proficiently mastered all the concepts covered by our articles, you’ll still probably have a few memory-related bugs.
Memory-related bugs may be particularly hard to spot and fix. Let’s take the following program as an example:
#define MAX_LINE_SIZE 32
static const char *build_message(const char *name)
sprintf(message, "hello %s!\n", name);
int main(int argc, char *argv)
fputs(build_message(argc > 1 ? argv : "world"), stdout);
This program is supposed to take a message as argument and print “hello <message>!” (the default message being “world”).
The behavior of this program is completely undefined, it is buggy, however it will probably not crash. The function
build_message returns a pointer to some memory allocated in its stack-frame. Because of how the stack works, that memory is very susceptible to be overwritten by another function call later, possibly by
fputs. As a consequence, if
fputs internally uses sufficient stack-memory to overwrite the message, then the output will be corrupted (and the program may even crash), in the other case the program will print the expected message. Moreover, the program may overflow its buffer because of the use of the unsafe
sprintf function that has no limit in the number of bytes written.
So, the behavior of the program varies depending on the size of the message given in the command line, the value of
MAX_LINE_SIZE and the implementation of
fputs. What’s annoying with this kind of bug is that the result may not be obvious: the program “works” well enough with simple use cases and will only fail the day it will receive a parameter with the right properties to exhibit the issue. That’s why it’s important that developers are at ease with some tools that will help them to validate (or to debug) memory management.
In this last article, we will cover some free tools that we consider should be part of the minimal toolkit of a C (and C++) developer.