Obfuscated C++
- By Rob Murray
- April 25, 2000
LAST MONTH'S OBFUSCATED C++
Last month we asked you to identify the error in the following file:
static char* saved = 0;
void saveString(const char* cp) {
delete saved;
saved = new char[strlen(cp)+1]; //corrected
strcpy(saved,cp);
}
char* getString( ) {
if(!saved) return 0;
char* rc = new char[strlen(saved)+1]; //corrected
strcpy(rc,saved);
return rc;
}
This file implements a simplistic string repository. A
char* string is saved by passing it to
saveString, and a copy of that string is fetched by calling
getString. This repository is clumsily implemented using functions instead of classes; but that is simply bad design, not an error.
Note that the first call to saveString will cause a delete of a 0 pointer. However, this is explicitly legal according to the language rules and has no effect. We also have no aliasing problems in saveString, because saved is a file static and is never returned by getString. This means it cannot be passed in to saveString.
The error is in the delete expression in saveString. Since saved points (in general) to an array of characters, the array form of delete must be used (delete[] saved;). As the code is written, the effect of the delete is undefined. Of course, this code will work (by luck) in the many programs where the default array new and delete for built-in types are the same as the nonarray versions.
However, if we link this code with a library that supplies nonstandard versions of the global operator new and operator new[] functions (and their corresponding deletes), this code may fail, because it will pass a pointer to the global operator delete function that was originally allocated by operator new[] instead of operator new. The overloaded operator delete is not required to handle this gracefully.
THIS MONTH'S OBFUSCATED C++
What is printed by the following program?
#include <iostream>
using namespace std;
static inline int f( ) {
static int g = 0;
return g++;
}
int main( ){
f( s);
cout << f( ) << endl;
return 0;
}
Hint: Does it make a difference that f is inline?
Rob Murray is Director of Operations at the Irvine office of Nuforia, an object-oriented software consulting company based in Houston, TX. He has taught C++ at technical conferences since 1987 and is the author of C++ Strategies and Tactics. He was the founding editor of the C++ Report and may be contacted at [email protected].
|