为什么使用asprintf()而不是sprintf()? [英] Why use asprintf() instead of sprintf()?

查看:707
本文介绍了为什么使用asprintf()而不是sprintf()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm having a hard time understanding why you would need asprintf. Here in the manual it says

函数asprintf()vasprintf()sprintf(3)vsprintf(3),除了它们分配的字符串足以容纳 输出包括终止的空字节,并返回一个指针 通过第一个参数.该指针应传递给 free(3)以在不再需要时释放已分配的存储.

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.

这是我想要理解的示例:

So here is the example that I'm trying to understand:

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

如果缓冲区分配的字符串大于说char * =(string)的区别是什么

What's the difference if the buffer allocates a string large enough vs saying char* = (string)

推荐答案

如果使用sprintf()vsprintf(),则需要首先分配一个缓冲区,并且需要确保该缓冲区足够大以包含该缓冲区. sprintf编写的内容.否则,sprintf()会很乐意覆盖超出缓冲区末尾的任何内存.

If you use sprintf() or vsprintf(), you need to allocate a buffer first, and you need to be sure that the buffer is large enough to contain what sprintf writes. Otherwise sprintf() will happily overwrite whatever memory lies beyond the end of the buffer.

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

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

... writes the '6' and the terminating null beyond the end of the space allocated to x, either corrupting some other variable, or causing a segmentation fault.

如果幸运的话,它会在分配的块之间践踏内存,这不会造成伤害-这次.这会导致间歇性错误,这是最难诊断的错误.最好使用诸如 ElectricFence 之类的工具,该工具会导致超速运行失败.

If you're lucky, it will trample on memory in-between allocated blocks, and will do no harm -- this time. This leads to intermittent bugs -- the hardest kind to diagnose. It's good to use a tool like ElectricFence that causes overruns to fail-fast.

提供过长输入的非恶意用户,可能会导致程序以意想不到的方式运行.恶意用户可以利用此方法将自己的可执行代码获取到系统中.

A non-malicious user who provides an overlong input, could cause the program to behave in unexpected ways. A malicious user could exploit this as a way to get their own executable code into the system.

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

One guard against this is to use snprintf(), which truncates the string to the maximum length you supply.

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

返回值size是在有可用空间的情况下将写入 的长度-不包括终止空值.

The return value size is the length that would have been written if space was available -- not including the terminating null.

在这种情况下,如果size大于或等于5,则说明发生了截断-如果不想截断,则可以分配一个新字符串,然后再次尝试.

In this case, if size is greater than or equal to 5 then you know that truncation occurred - and if you didn't want truncation, you could allocate a new string and try snprintf() again.

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");
}

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

(That's a pretty naive algorithm, but it illustrates the point. There may yet be bugs in it, which further illustrates the point -- this stuff is easy to screw up.)

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

asprintf() does this in one step for you - calculates the length of the string, allocates that amount of memory, and writes the string into it.

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

在所有情况下,完成x后,您都需要释放它,否则会泄漏内存:

In all cases, once you've finished with x you need to release it, or you leak memory:

free(x);

asprintf()是隐式的malloc(),因此您必须检查它是否起作用,就像使用malloc()或任何其他系统调用一样.

asprintf() is an implicit malloc(), so you have to check it worked, just as you would with malloc() or any other system call.

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

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

Note that asprintf() is part of the GNU and BSD extensions to libc - you can't be sure it will be available in every C environment. sprintf() and snprintf() are part of the POSIX and C99 standards.

这篇关于为什么使用asprintf()而不是sprintf()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆