I'm working on the AVR platform. avr-libc does not provide asprintf()
. A library I'm attempting to bring into my project requires it. Helpfully, that same library includes an implementation (below). Unfortunately, it is providing odd results. Specifically, I've determined that the return code of vsnprintf()
is never correct; rather than random results, I seem to always see the same progression of incorrect values (5, 1, etc.) upon successive calls.
The call to this function is: asprintf(&str, "%s[%d]", name, val);
. str
is a char*
on the stack within the calling function. name
is a simple short text descriptor that I've verified is not null and not zero length. val
is a simple index that is incremented within the loop that calls asprintf()
. The resulting string this call builds should be 7 characters long (not including null terminator). asprintf()
is called throughout the library. My use of the containing library only ever executes it in this single loop (twice). The library does its job as expected if I remove this call and replace the results with dummy values. Execution seemingly crashes at assigning the buffer to the dereferenced ret
pointer within the implementation of asprintf()
.
Despite lots of experiments with buffers, pointer dereferencing, and managing var args I cannot get this function to operate properly. However, cross-compiled on OS X it works just fine.
I know that the behavior of vsnprintf()
is not necessarily identical across all platforms. That said, as far as I can tell this usage should work as expected.
Any ideas? Could it be something outside the function itself? Some kind of stdio initialization or linker library option that is causing the trouble?
int asprintf(char **ret, const char *fmt, ...) {
va_list ap1;
va_list ap2;
int count;
va_start(ap1, fmt);
va_copy(ap2, ap1);
count = vsnprintf(NULL, 0, fmt, ap1);
va_end(ap1);
if(count > 0) {
char* buffer;
if (!(buffer = (char*)malloc(count+1))) {
return -1;
}
count = vsnprintf(buffer, count+1, fmt, ap2);
*ret = buffer;
}
va_end(ap2);
return count;
}