简体   繁体   中英

Integer to string in C without preallocated char array

Please, look at the following code that just convert an unsigned int to a string (there may be some unhandled cases but it's not my question), allocating a char array in the heap and returning it, leaving the user the responsibility to free it after the use. Can you explain me why such function (and others similar) do not exist in C standard library? Yes, printf("%s\\n", itos(5)) is a memory leak, but this programming pattern is already used and is consider a good practice[1]. IMO, if such functions had existed since the dawn of C we would had little memory leaks more but tons of buffer overflows less!

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

char* itos(unsigned int value)
{
    int string_l = (value == 0) ? 1 : (int)log10(value) + 1;
    char *string = malloc((string_l + 1) * sizeof(char));
    int residual = value;
    int it;
    for (it = string_l - 1; it >= 0; it--) {
        int digit;
        digit = residual % 10;
        residual = residual / 10;
        string[it] = '0' + digit;
    }
    string[string_l] = '\0';
    return string;
}

int main(void)
{
    char* string = itos(534534345);
    printf("%s\n", string);
    free(string);
    return 0;
}

[1] http://www.opengroup.org/onlinepubs/009695399/functions/getaddrinfo.html

EDIT:

Habbie's answer:

char *string;
asprintf(&string, "%d", 155);
printf("%s\n", string);
free(string);

In my eyes, memory management is up to the caller, not the callee. For instance, when I'm not using the standard malloc() implementation throughout my program I would be very upset about having to find and call the corresponding free() , the upshot is I wouldn't use such a function.

Edit: Your getaddrinfo() example is perfect, they provide both getaddrinfo() and freeaddrinfo() , that's the only way to make sure I'm calling the right free() .

原来asprintf是您需要的:)

Programming has evolved since it was created - this is simply something that wasn't present since the dawn of C, but has evolved in other languages since. I particularly like the way objective-c handles this by returning a string object which has been autoreleased (meaning it will be automatically freed later on, after the object has gone out of scope). You could implement something similar in C if you wanted to:

  1. create a pool for temporary allocations outside your main loop
  2. allocate from the pool as needed using your own allocation function
  3. periodically free the pool at a shallow level in your call stack (for example once per cycle in your very outer main loop)

Another way to achieve the same thing, but allowing you to use system functions that use malloc to allocate memory:

  1. outside your main loop create a list (initially empty) of 'to-be-freed' objects
  2. write a function called 'autofree' that adds pointers to the list and returns the pointer
  3. whenever you need to use it like this: printf("%s\\n", autofree(itos(5)));
  4. each time round your main loop, free all the pointers in the list and empty the list

If you do this in a nice way, you can create multiple such autofree pools and nest them around inner loops that potentially create lots of allocations that you want to be freed sooner rather than back in your main loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM