繁体   English   中英

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

[英]Integer to string in C without preallocated char array

请看下面的代码,它们只是将unsigned int转换为字符串(可能有一些未处理的情况,但这不是我的问题),在堆中分配一个char数组并返回它,让用户有责任在之后释放它使用。 您能解释一下为什么C标准库中不存在这样的功能(以及其他类似功能)吗? 是的, printf("%s\\n", itos(5))是内存泄漏,但是已经使用了这种编程模式,被认为是一种很好的做法[1]。 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

编辑:

哈比的答案:

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

在我看来,内存管理取决于调用者,而不是被调用者。 例如,当我在整个程序中不使用标准的malloc()实现时,我不得不查找并调用相应的free()会很不高兴,结果是我不会使用这样的功能。

编辑:您的getaddrinfo()示例是完美的,它们同时提供getaddrinfo()freeaddrinfo() ,这是确保我调用正确的 free()的唯一方法。

原来asprintf是您需要的:)

自创建以来,编程已经发生了演变-这只是自C诞生以来就没有出现过的东西,但是自那以后它已经在其他语言中得到了发展。 我特别喜欢Objective-C通过返回一个已自动释放的字符串对象处理此问题的方式(这意味着在对象超出范围后,它将在以后自动释放)。 如果您愿意,可以在C中实现类似的功能:

  1. 在主循环外创建用于临时分配的池
  2. 使用自己的分配功能根据需要从池中进行分配
  3. 定期在调用堆栈的浅层释放池(例如,在最外部的主循环中每个周期一次)

实现相同功能的另一种方法,但是允许您使用使用malloc分配内存的系统函数:

  1. 在主循环之外创建“待释放”对象的列表(最初为空)
  2. 编写一个名为“ autofree”的函数,该函数将指针添加到列表中并返回指针
  3. 每当您需要像这样使用它时: printf("%s\\n", autofree(itos(5)));
  4. 每次绕过主循环时,释放列表中的所有指针并清空列表

如果以一种不错的方式执行此操作,则可以创建多个这样的自动释放池,并将它们嵌套在内部循环中,这样可能会创建许多要早日释放而不是返回主循环的分配。

暂无
暂无

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

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