我有一个使用sprintf的简单代码
#include <stdio.h>
int main()
{
char str_src [1024]={"Hello"};
sprintf(str_src,"%s%s",str_src,"hiiiiiiiiiii");
printf("result = %s",str_src);
}
Run Code Online (Sandbox Code Playgroud)
当我编译我得到正确的结果:
结果= Hellohiiiiiiiiiii
但由于sprintf不安全,我决定将其更改为snprintf.我觉得这很简单.我将sprintf更改为snprintf,如下所示
snprintf(str_src,1024,"%s%s",str_src,"hiiiiiiiiiii");
Run Code Online (Sandbox Code Playgroud)
现在,如果我编译并运行代码,我会得到不同的结果
结果= hiiiiiiiiiii
如果我使用str_src作为第四个参数(作为%s的值),我将面临这个问题.令人惊讶的是为什么snprintf的行为与sprintf不同?
Som*_*ude 11
使用相同的缓冲区作为目标和源是未定义的行为.
从C11规范(7.21.6.6/2):
如果在重叠的对象之间进行复制,则行为未定义.
对于snprintf(7.21.6.5/2)也是如此,并且对于va_list变体也是如此.
不幸的是,它在运行代码时很常见,但它并不能真正依赖于工作.
从sprintf联机帮助页:
C99 和 POSIX.1-2001 指定如果调用 sprintf()、snprintf()、vsprintf() 或 vsnprintf() 会导致在重叠的对象之间进行复制(例如,如果目标字符串数组和提供的输入参数之一引用同一个缓冲区)。见注释。
这个问题真的没有答案,因为您的代码具有未定义的行为。
| 归档时间: |
|
| 查看次数: |
2929 次 |
| 最近记录: |