-1

I want to use mysprintf () instead of sprintf () for automatic buffer size allocation.

Is there any problem with mysprintf()? Or can you recommend a better way?

char s[256];
sprintf(s, "%s-%s-%s", "abcdefg", "abcdefg", "abcdefg");
string s = mysprintf("%s-%s-%s", "abcdefg", "abcdefg", "abcdefg");
string mysprintf(const char* format, ...)
{
    int ret;
    char* buf;
    va_list ap;

    va_start(ap, format);
    ret = vasprintf(&buf, format, ap);
    va_end(ap);

    if (ret == -1) {
        return {};
    }

    string out(buf);
    free(buf);

    return out;
}
Benjamin
  • 7
  • 2
  • 1
    You are walking a path of great pain, trying to take all of the disadvantages of `sprintf` with little to show for it. Has anyone introduced you to [parameter packs](https://en.cppreference.com/w/cpp/language/parameter_pack)? This will still be painful as all hell, but type safe. – user4581301 Sep 04 '19 at 04:52
  • Seems fine to me in principle (ignoring type safety), although strictly speaking it's not exception-safe; if `std::string`'s constructor throws, you've leaked memory. – jamesdlin Sep 04 '19 at 05:25
  • Unless you want to learn about what's wrong with your existing code. – user202729 Sep 04 '19 at 05:26
  • At the very least, you should wrap the allocated `buf` in a `std::unique_ptr` with a custom deleter to call `free()` – Remy Lebeau Sep 04 '19 at 06:12
  • `vasprintf()` is GNU specific. If your compiler is compatible with C99 - or supports the C99 standard library - you can use `vsnprintf()` to, (1) obtain a required buffer (2) allocate a container (`std::string` or a `std::vector`) of appropriate size and (3) write the data directly to that container. The benefit of this alternative is that all the allocations are cleanly deallocated (no need to call `free()` manually, and no opportunity to inadvertently not do so). – Peter Sep 04 '19 at 06:28

1 Answers1

-1

You don't need to write your own function, use asprintf() instead.

But notice that it is a USE_GNU stuff.

Remember to free()

lilington
  • 83
  • 5