2

I want to allocate a dynamic memory to a buffer, and I am storing the data in it through vsprintf();. I am creating a logging mechanism that requires the use of vsprintf and every time my data is different so I want to allocate dynamic memory to the buffer. But I don't know how I can get the size of the format and va_list args.

I have no clue from where I can start and how can I get the buffer length

Any help would be great.

Thank you!

Maaz Sk
  • 123
  • 4
  • Please provide a [mre]. I propose to create it by using a huge buffer (large enough for the at least two different sets of data) and showing how the same call to vsprintf() gets differently sized data. – Yunnosch Mar 31 '22 at 05:47
  • 1
    Okay sure just give me a little time I will share it with you. – Maaz Sk Mar 31 '22 at 05:49
  • Of course take your time. You have the option to delete your question, edit it for improval and when you are satisfied undelete it. That way it will only be judged when you are ready. Good luck. – Yunnosch Mar 31 '22 at 05:51
  • Actually, I just solved the issue should I delete the question? – Maaz Sk Mar 31 '22 at 05:59
  • 1
    Either that or, even better, show your solution in an answer you create. Just make sure that all the info someone else would have needed to answer is in the question. E.g. [ask], [mre]. – Yunnosch Mar 31 '22 at 06:01
  • 1
    Does https://stackoverflow.com/questions/3774417/sprintf-with-automatic-memory-allocation answer your quesiton? – KamilCuk Mar 31 '22 at 06:03
  • @KamilCuk Yes, the link which you shared is the similar solution that I implemented – Maaz Sk Mar 31 '22 at 06:35

1 Answers1

2

You should not use vsprintf() because there is no way to tell this function the size of the destination array. You should instead use vsnprintf() and you can compute the length of the formatted string from the return value of vsnprintf().

Here is an example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int logstuff(const char *fmt, ...) {
    char buffer[256];
    char *str;
    int length;
    va_list args;

    /* format the message into a local buffer */
    va_start(args, fmt);
    length = vsnprintf(buffer, sizeof buffer, fmt, args);
    va_end(args);

    if (length < 0) {
        /* encoding error */
        [...]
        return -1;
    }

    if ((unsigned)length < sizeof buffer) {
        /* message is OK, allocate a copy */
        str = strdup(buffer);
    } else {
        /* message was truncated, allocate a large enough array */
        str = malloc(length + 1U);
    }
    if (!str) {
        /* allocation error */
        [...]
        return -1;
    }
    if ((unsigned)length >= sizeof buffer) {
        /* format the message again */
        va_start(args, fmt);
        length = vsnprintf(str, length + 1U, fmt, args);
        va_end(args);
    }

    /* store the message somewhere */
    [...]

    return length;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189