I tried @Valentin Milea's code but I've got access violation errors. The only thing that worked for me was Insane Coding's implementation: http://asprintf.insanecoding.org/
Specifically, I was working with VC++2008 legacy code. From Insane Coding's implementation (can be downloaded from the link above), I used three files: asprintf.c, asprintf.h and vasprintf-msvc.c. Other files were for other versions of MSVC.
[EDIT] For completeness, their contents are as follows:
asprintf.h:
#ifndef INSANE_ASPRINTF_H #define INSANE_ASPRINTF_H #ifndef __cplusplus #include <stdarg.h> #else #include <cstdarg> extern "C" { #endif #define insane_free(ptr) { free(ptr); ptr = 0; } int vasprintf(char **strp, const char *fmt, va_list ap); int asprintf(char **strp, const char *fmt, ...); #ifdef __cplusplus } #endif #endif
asprintf.c:
#include "asprintf.h" int asprintf(char **strp, const char *fmt, ...) { int r; va_list ap; va_start(ap, fmt); r = vasprintf(strp, fmt, ap); va_end(ap); return(r); }
vasprintf-msvc.c:
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include "asprintf.h" int vasprintf(char **strp, const char *fmt, va_list ap) { int r = -1, size = _vscprintf(fmt, ap); if ((size >= 0) && (size < INT_MAX)) { *strp = (char *)malloc(size+1); //+1 for null if (*strp) { r = vsnprintf(*strp, size+1, fmt, ap); //+1 for null if ((r < 0) || (r > size)) { insane_free(*strp); r = -1; } } } else { *strp = 0; } return(r); }
Usage (part of test.c provided by Insane Coding):
#include <stdio.h> #include <stdlib.h> #include "asprintf.h" int main() { char *s; if (asprintf(&s, "Hello, %d in hex padded to 8 digits is: %08x\n", 15, 15) != -1) { puts(s); insane_free(s); } }