gpt4 book ai didi

c - 为什么使用 asprintf() 而不是 sprintf()?

转载 作者:太空狗 更新时间:2023-10-29 16:19:10 31 4
gpt4 key购买 nike

我很难理解您为什么需要 asprintf。在手册中它说

The functions asprintf() and vasprintf() are analogs of sprintf(3) and vsprintf(3), except that they allocate a string large enough to hold the output including the terminating null byte, and return a pointer to it via the first argument. This pointer should be passed to free(3) to release the allocated storage when it is no longer needed.

下面是我试图理解的示例:

asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));

如果缓冲区分配一个足够大的字符串与说 char* = (string) 有什么区别

最佳答案

如果使用sprintf()或者vsprintf(),需要先分配一个buffer,并且需要保证buffer足够大,可以容纳sprintf 写了什么。否则 sprintf() 将愉快地覆盖缓冲区末尾之外的任何内存。

char* x = malloc(5 * sizeof(char));
// writes "123456" +null but overruns the buffer
sprintf(x,"%s%s%s", "12", "34", "56");

... 在分配给 x 的空间末尾写入 '6' 和终止 null,要么破坏其他变量,要么导致段错误.

如果幸运的话,它会在分配的 block 之间践踏内存,并且不会造成伤害——这一次。这会导致间歇性错误——最难诊断的错误。最好使用像 ElectricFence 这样的工具,它会导致超限以快速失败。

提供超长输入的非恶意用户可能会导致程序以意想不到的方式运行。恶意用户可能会利用这一点将他们自己的可执行代码获取到系统中。

防止这种情况的一种方法是使用 snprintf(),它将字符串截断为您提供的最大长度。

char *x = malloc(5 * sizeof(char));
int size = snprintf(x, 5, "%s%s%s", "12", "34", "56"); // writes "1234" + null

返回值 size 是在空间可用的情况下写入的长度 -- 不包括终止 null。 p>

在这种情况下,如果 size 大于或等于 5,那么您就知道发生了截断 - 如果您不想截断,则可以分配一个新字符串并尝试 再次使用 snprintf()

char *x = malloc(BUF_LEN * sizeof(char));
int size = snprintf(x, 5, "%s%s%s", "12", "34", "56");
if (size >= BUF_LEN) {
realloc(&x,(size + 1) * sizeof(char));
snprintf(x, size + 1 , "%s%s%s", "12", "34", "56");
}

(这是一个非常幼稚的算法,但它说明了这一点。它可能还存在错误,这进一步说明了这一点——这东西很容易搞砸。)

asprintf() 为您一步完成 - 计算字符串的长度,分配该数量的内存,然后将字符串写入其中。

char *x;
int size = asprintf(&x, "%s%s%s", "12", "34", "56");

在所有情况下,一旦完成 x 就需要释放它,否则会泄漏内存:

free(x);

asprintf() 是一个隐含的 malloc(),因此您必须检查它是否正常工作,就像使用 malloc() 一样或任何其他系统调用。

if (size == -1 ) {
/* deal with error in some way */
}

请注意,asprintf() 是 GNU 和 BSD 对 libc 的扩展的一部分 - 您不能确定它在每个 C 环境中都可用。 sprintf()snprintf() 是 POSIX 和 C99 标准的一部分。

关于c - 为什么使用 asprintf() 而不是 sprintf()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12746885/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com