snprintf负值/缓冲区大小的零值

时间:2016-05-25 09:21:38

标签: c printf buffer

如果将负数或0作为第二个参数传递给snprintf(),它是否会在提供的缓冲区位置写入。想知道这不会导致任何意外行为。

int snprintf(char *str, size_t size, const char *format, ...);

3 个答案:

答案 0 :(得分:9)

引用C11,chpater§7.21.6.5, snprintf()函数

  

int snprintf(char * restrict s, size_t n,const char * restrict format, ...);

     

[...]如果n为零,则不写任何内容,   并且s可能是空指针。

因此,如果您传递0,则不会写任何内容。

如果您传递- ve值,则可能会产生问题,因为第二个参数的类型为size_t unsigned。因此,签名值将被视为unsigned,产生不需要的大小。这可能会导致问题(内存溢出),因为大小可能超过提供的缓冲区可以处理的内容,这会调用undefined behavior。 。然而,只要缓冲区足够大以便能够保存提供的数据,所提供的数据就会被写入缓冲区。

来自§7.19,<stddef.h>

  

size_t
  这是sizeof运算符的结果的无符号整数类型;

答案 1 :(得分:4)

0传递给snprintf没有字符将被插入dest缓冲区。

将一个负数传递给一个size_t参数,即unsigned,您传递的数字非常大size

尝试

printf("%zu\n%zu\n", (size_t)(-1),  SIZE_MAX);

因此,使用负大小参数,您可以写出比真实目标缓冲区大小更多的字节,换句话说就是未定义行为/缓冲区溢出。

答案 2 :(得分:0)

虽然现有答案是正确的,当说给定大小为0时不会将字节写入目标缓冲区时,它们无法通知您,在这种情况下,返回值snprintf将是格式参数大小的总和。有时可能会很方便地意识到这一点:)

从手册:

  

返回值

     

成功返回后,这些函数返回数字   打印的字符数(不包括用于结束输出到的空字节)   字符串)。

     

函数snprintf()和vsnprintf()的写操作不超过size   字节(包括终止的空字节('\ 0'))。 如果输出   由于此限制而被截断,则返回值为   字符数(不包括终止的空字节)   如果有足够的空间已被写入最终字符串   。因此,返回值size或更大意味着   输出被截断。 (另请参见以下“注释”下的内容。)

     

如果遇到输出错误,则返回负值。