Tuesday, 5 April 2011

Temporary File names in C & C++ in Windows and Linux

So, I ran into a little bit of a programming problem involving the C call “tmpnam” which is used to generate you a temporary file name in C and C++. It's not a safe call, because other libraries and applications might call “tmpnam” before you get to use the name given, and they might grab the same file name. But my code needed to generate just a file name... so this will suffice for me (I'll so checking etc. myself).

Anyway, the problem comes up when, in a mix of brain-dead and bad document mode I do this:

char* l_temporaryBuffer = new char[L_tmpnam];
int l_error = tmpnam (l_temporaryBuffer, l_tmpnam);

It leaked memory, in fact it leaked 12 bytes per call, and I was just so brain frazzled at 2am last night that I couldn't wrap my head around why, in the cold light of day however I know why, its because I'm a cock, the 12 bytes were from this buffer... you don't need to assign memory to the buffer you pass in, tmpnam stores the resultant string in a static location.

This was painfully demonstrated when I tried to delete l_temporaryBuffer and was promptly told I had corrupted my application's heap.

So, the correct way of using tmpnam, on Windows and Linux is:

char* l_ptrBuffer;
l_ptrBuffer = tmpnam(NULL);

Or if you're going to use windows you'll likely get a warning that tmpnam is unsafe, and if like me you heed the advice of your warnings (as you all should) you'll want to use tmpnam_s, so on Windows the corrected code is:

char *l_ptrBuffer;
int l_error = tmpnam_s (l_ptrBuffer, L_tmpnam);
if ( error == 0 )
{
    // use the buffer it's valid
}
else
{
    // Scream blue murder the file name is invalid
}

What you should never do is delete[] l_ptrBuffer. In this code, it's not your string to delete, its a static in your runtime.

Likewise if you use tmpnam and get a heap corruption, it maybe because you are disposing of memory which is not yours. Beware.

No comments:

Post a Comment