Subtle Errors in C++ Programs

I recently stumbled upon a subtle bug in a benchmark code which again reminds me to never use C++ again, if I can.

Here’s a buggy snippet from this code (simplified):

// BUGGY
ostringstream os;
int i = 1;
os << "foo-" << i << ".dat";
const char *filename = os.str().c_str();
int fd = open(filename, O_RDONLY);

You may expect above code to try open a file named foo-1.dat but that’s not what is happening here.

In this snippet, os.str() create a temporary string object which is destroyed immediately after call to c_str() method. So, filename ends up pointing to freed memory which can of course contain arbitrary content (till you reach a NULL).

This fix would be to first assign result of os.str() to a string object explicitly which would have lifetime of the current scope:

// FIXED
ostringstream os;
int i = 1;
os << "foo-" << i << ".dat";
string s = os.str();
const char *filename = s.c_str();
int fd = open(filename, O_RDONLY);

Such bugs would be much harder to catch and fix in larger programs with complicated abstractions, typical of C++ programs.

Fortunately, we now have alternative languages like Rust which can detect such errors at compile time while giving a level of control and performance equivalent to C/C++.


See also