Correct memory allocation?

How would I allocate as much memory as needed without knowing how large the arguments to the function are?

I usually use fixed size and calculate the rest with sizeof(note: the code should not make sense, but to show the problem):

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

int test(const char* format, ...)
{
    char* buffer;
    int bufsize;
    int status;
    va_list arguments;
    va_start(arguments, format);
    bufsize = 1024; /* fixed size */
    bufsize = sizeof(arguments) + sizeof(format) + 1024;
    buffer = (char*)malloc(bufsize);
    status = vsprintf(buffer, format, arguments);
    fputs(buffer, stdout);
    va_end(arguments);
    return status;
}

int main()
{
    const char* name = "World";
    test("Hello, %s\n", name);
    return 0;
}

However, I don't think this is the way ... so how would I correctly calculate the required buffering?

+3
source share
1 answer

If you have vsnprintf, available to you, I would take advantage of this. It prevents buffer overflows because you provide a buffer size, and it returns the required actual size.

, 1K-, vsnprintf , . , , .

, realloc, . (, ), , , .

. , (. ).

vsnprintf -type, , , - /dev/null ( ). vfprintf , ( -), vsprintf . , , .


, 1K-. malloc , , .

, - :

int test(const char* format, ...)
{
    char buff1k[1024];
    char *buffer = buff1k; // default to local buffer, no malloc.
    :
    int need = 1 + vsnprintf (buffer, sizeof (buff1k), format, arguments);
    if (need > sizeof (buff1k)) {
        buffer = malloc (need);
        // Now you have a big-enough buffer, vsprintf into there.
    }

    // Use string at buffer for whatever you want.
    ...

    // Only free buffer if it was allocated.
    if (buffer != buff1k)
        free (buffer);
}
+7
source

Source: https://habr.com/ru/post/1764423/


All Articles