Note that there are some explanatory texts on larger screens.

plurals
  1. PORegarding vsnprintf (Interview)
    text
    copied!<p>During an interview I was requested (among other things) to implement the following function:</p> <pre><code>int StrPrintF(char **psz, const char *szFmt, ...); </code></pre> <p>similar to <code>sprintf</code>, except instead of the already-allocated storage the function must allocate it itself, and return in the <code>*psz</code> variable. Moreover, <code>*psz</code> may point to an already-allocated string (on the heap), which may potentially be used during the formatting. Naturally this string must be free by the appropriate means.</p> <p>The return value should be the length of the newly created string, or negative on error.</p> <p>This is my implementation:</p> <pre><code>int StrPrintF(char **psz, const char *szFmt, ...) { va_list args; int nLen; va_start(args, szFmt); if ((nLen = vsnprintf(NULL, 0, szFmt, args)) &gt;= 0) { char *szRes = (char*) malloc(nLen + 1); if (szRes) if (vsnprintf(szRes, nLen + 1, szFmt, args) == nLen) { free(*psz); *psz = szRes; } else { free(szRes); nLen = -1; } else nLen = -1; } va_end(args); return nLen; } </code></pre> <p>The question author claims there's a bug in this implementation. Not just a standard violation that <em>may</em> fail on particular esoteric systems, but a "real" bug, which by chance may fail on most systems.</p> <p>It's also not related to usage of <code>int</code> instead of memory-capability-suited type, such as <code>size_t</code> or <code>ptrdiff_t</code>. Say, the strings are of "reasonable" size.</p> <p>I really have no clue of what the bug could be. All the pointer arithmetic is ok IMHO. I even don't assume that two consequent invocations of <code>vsnprintf</code> produce the same result. All the variadic-handling stuff is also correct IMHO. <code>va_copy</code> is not needed (it's the responsibility of the callee that uses <code>va_list</code>). Also on x86 <code>va_copy</code> and <code>va_end</code> are meaningless.</p> <p>I'll appreciate if someone can spot the (potential) bug.</p> <p><strong>EDIT:</strong></p> <p>After checking out the answers and comments - I'd like to add some notes:</p> <ul> <li>Naturally I've built and run the code with various inputs, including step-by-step in debugger, watching the variables state. I'd never ask for help without trying things myself first. I saw no sings of problems, no stack/heap corruption, etc. Also I've run it in debug build, with the debug heap enabled (which is intolerant to heap corruption).</li> <li>I assume that the function is called with valid parameters, i.e. <code>psz</code> is a valid pointer (not to confuse with <code>*psz</code>), <code>szFmt</code> is a valid format specifier, and all the variadic parameters are evaluated and correspond to the format string.</li> <li>Calling <code>free</code> with <code>NULL</code> pointer is ok according to the standard.</li> <li>Calling <code>vsnprintf</code> is ok with <code>NULL</code> pointer and size=0. It should return the resulting string length. MS-version, though not fully standard-compliant, does the same in this specific case.</li> <li><code>vsnprintf</code> won't exceed the specified buffer size, including the 0-terminator. Means - it does not always places it.</li> <li>Please put the coding style aside (if you don't like it - fine with me).</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload