Use elementsof(sz), not sizeof(sz)
I had to fix a bug recently where my shell extension was crashing another application when you used that app’s File Open dialog.
This application has a thumbnail view of the selected file in the File Open dialog, which they generate the same way as Windows Explorer: by loading a shell extension for the selected filetype and calling its
IExtractImage interface. It’s a fairly weird protocol: First they call your
IPersistFile::Load to give you the filename, then you give them back the same filename when they call
IExtractImage::GetLocation. Finally they call
IExtractImage::Extract and that’s when you generate the thumbnail.
But, after my
GetLocation method returned, the application silently exited. What could be wrong? My code worked fine in Explorer.
GetLocation is a typical function that takes a character string buffer and length along with some other parameters (omitted here):
I noticed that this other app was giving me an unusually large file pathname buffer, 520 characters or 1040 bytes to be exact. This number sounded strangely familiar (and not just because of this).
Then I realized what happened. I’ve never seen the source code for this app I was crashing, but I just know it looked like this:
cchMax argument to
GetLocation is a length in characters, but
sizeof gives you the size in bytes. And we’re talking
WCHAR here, so each character is two bytes.
MAX_PATH is 260, making
szPath 520 bytes long, the number that they passed into my code.
One way to fix the problem is:
That gives correct code, but I never like seeing
MAX_PATH repeated like this.
sizeof is in the right spirit, actually measuring the array length instead of repeating a constant, but it measures the wrong thing, bytes instead of characters (array elements).
I like to code this with the
elementsof macro, defined as:
Then you can just use
elementsof instead of
elementsof is handy anytime you need the length of a character string array or any array.
Of course, I didn’t have the luxury of fixing this code at its source (other than reporting the bug to the program’s authors). So I worked around it by checking for the bogus 520 character
cchMax and cutting it back to 260 (