Search code examples
cwinapibufferallocation

Why is 40 added to the size passed to LocalAlloc?


The example code for Retrieving the Last-Error Code on MSDN shows this code:

lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
    (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));

which is used later in

StringCchPrintf((LPTSTR)lpDisplayBuf, 
    LocalSize(lpDisplayBuf) / sizeof(TCHAR),
    TEXT("%s failed with error %d: %s"), 
    lpszFunction, dw, lpMsgBuf); 

I am very curious to know why exactly that 40 is added?

Is that some safety margin? Or is Microsoft trying to tell us something about StringCchPrintf? Or something else?


Solution

  • Given the format string %s failed with error %d: %s, there are 21 characters of text (" failed with error " and ": "). The longest representation of an error code (0x8FFFFFFF or -1879048193 in decimal) is 11 characters long. Take another character for the null terminator, and you have a grand total of 33 characters, plus the lengths of the two input strings. The code thus over-allocates space for 7 characters.

    That could mean that the author was in a hurry, estimated the required buffer size, slightly over-estimating it just in case, or a technical writer fixing the error text without accounting for it in code.

    We don't really know, but if you are using Visual Studio and don't want to do the math yourself, you can have the CRT do it for you by calling any of the _vsctprintf family of functions. Not only is this immune to changes of the format string, it also documents the author's intent to the point, where no questions are left unanswered.