Search code examples
cdynamic-memory-allocation

How much space to allocate for printing long int value in string?


I want to store a long value (LONG_MAX in my test program) in a dynamically allocated string, but I'm confused how much memory I need to allocate for the number to be displayed in the string.

My fist attempt:

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

int main(void)
{
    char *format = "Room %lu somedata\n";
    char *description = malloc(sizeof(char) * strlen(format) + 1);

    sprintf(description, format, LONG_MAX);

    puts(description);

    return 0;
}

Compiled with

gcc test.c

And then running it (and piping it into hexdump):

./a.out | hd 

Returns

00000000  52 6f 6f 6d 20 39 32 32  33 33 37 32 30 33 36 38  |Room 92233720368|
00000010  35 34 37 37 35 38 30 37  20 62 6c 61 62 6c 61 0a  |54775807 blabla.|
00000020  0a                                                |.|
00000021

Looking at the output, it seems my memory allocation of sizeof(char) * strlen(format) + 1 is wrong (too less memory allocated) and it works more accidentally?

What is the correct amount to allocate then?

My next idea was (pseudo-code):

sizeof(char) * strlen(format) + strlen(LONG_MAX) + 1

This seems too complicated and pretty non-idomatic. Or am I doing something totally wrong?


Solution

  • You are doing it totally wrong. LONG_MAX is an integer, so you can't call strlen (). And it's not the number that gives the longest result, LONG_MIN is. Because it prints a minus character as well.

    A nice method is to write a function

    char* mallocprintf (...)
    

    which has the same arguments as printf and returns a string allocated using malloc with the exactly right length. How you do this: First figure out what a va_list is and how to use it. Then figure out how to use vsnprintf to find out how long the result of printf would be without actually printing. Then you call malloc, and call vsnprintf again to produce the string.

    This has the big advantage that it works when you print strings using %s, or strings using %s with some large field length. Guess how many characters %999999d prints.