我有一个使用sprintf的简单代码
#include <stdio.h>
int main()
{
char str_src [1024]={"Hello"};
sprintf(str_src,"%s%s",str_src,"hiiiiiiiiiii");
printf("result = %s",str_src);
}
当我编译时,我得到了正确的结果:
结果= Hellohiiiiiiiiiii
但由于sprintf不安全,我决定将其改为snprintf。我以为这会很简单。我将sprintf改为snprintf,如下所示
snprintf(str_src,1024,"%s%s",str_src,"hiiiiiiiiiii");
现在,如果编译并运行代码,就会得到不同的结果。
结果= hiiiiiiiiiii
如果我使用str_src作为第四个参数(作为%s的值),我将面临这个问题。为什么snprintf的行为与sprintf不同?
发布于 2013-10-21 01:04:22
使用与目标和源相同的缓冲区是未定义的行为。
来自C11规范(7.21.6.6/2):
如果复制发生在重叠的对象之间,则行为是未定义的。
snprintf
(7.21.6.5/2)也是如此,va_list
变体也是如此。
不幸的是,这在运行代码中是很常见的,但是不能真正依靠它来工作。
发布于 2013-10-21 01:04:57
来自sprintf
手册:
C99和POSIX1.2001指定,如果调用sprintf()、snprintf()、vsprintf()或vsnprintf()将导致重叠的对象之间进行复制(例如,如果目标字符串数组和提供的输入参数之一引用同一个缓冲区),则结果是未定义的。见注。
这个问题没有答案,因为您的代码有未定义的行为。
发布于 2013-10-21 01:05:02
不,在这两种情况下都会得到完全任意的结果,因为这是未定义的行为。其中一个恰好是你想要的。在不同的计算机上你可能得到不同的结果。不管它的价值是什么,它可能会格式化您的硬盘驱动器,但仍然是正确的行为。只是不要使用重叠的源和目标。
https://stackoverflow.com/questions/19490134
复制相似问题