简体   繁体   English

没有预分配char数组的C中字符串的整数

[英]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. 请看下面的代码,它们只是将unsigned int转换为字符串(可能有一些未处理的情况,但这不是我的问题),在堆中分配一个char数组并返回它,让用户有责任在之后释放它使用。 Can you explain me why such function (and others similar) do not exist in C standard library? 您能解释一下为什么C标准库中不存在这样的功能(以及其他类似功能)吗? Yes, printf("%s\\n", itos(5)) is a memory leak, but this programming pattern is already used and is consider a good practice[1]. 是的, printf("%s\\n", itos(5))是内存泄漏,但是已经使用了这种编程模式,被认为是一种很好的做法[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! IMO,如果这样的功能已经从C的曙光,我们将有小内存泄漏存在以上,但缓冲区溢出的少!

#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 [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. 例如,当我在整个程序中不使用标准的malloc()实现时,我不得不查找并调用相应的free()会很不高兴,结果是我不会使用这样的功能。

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() . 编辑:您的getaddrinfo()示例是完美的,它们同时提供getaddrinfo()freeaddrinfo() ,这是确保我调用正确的 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. 自创建以来,编程已经发生了演变-这只是自C诞生以来就没有出现过的东西,但是自那以后它已经在其他语言中得到了发展。 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). 我特别喜欢Objective-C通过返回一个已自动释放的字符串对象处理此问题的方式(这意味着在对象超出范围后,它将在以后自动释放)。 You could implement something similar in C if you wanted to: 如果您愿意,可以在C中实现类似的功能:

  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: 实现相同功能的另一种方法,但是允许您使用使用malloc分配内存的系统函数:

  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 编写一个名为“ autofree”的函数,该函数将指针添加到列表中并返回指针
  3. whenever you need to use it like this: printf("%s\\n", autofree(itos(5))); 每当您需要像这样使用它时: 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. 如果以一种不错的方式执行此操作,则可以创建多个这样的自动释放池,并将它们嵌套在内部循环中,这样可能会创建许多要早日释放而不是返回主循环的分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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