问题描述
#include <stdio.h>
#include <string.h>
int main() {
struct test
{
char buff[255];
char sour2[30];
};
struct test p;
char sour1[255] = "try to do code";
strcpy(p.sour2,"Create experimental data. Just take the regular simulation data and add some gaussian noise to it.");
int n = snprintf(p.buff,255,"%s",sour1);
printf("%s\n %s \n",p.buff,sour1);
}
预期输出:
try to do code
try to do code
我得到的是:
ake the regular simulation data and add some gaussian noise to it.
ake the regular simulation data and add some gaussian noise to it.
为什么我得到这个输出?因为sour1
,p.sour2
位于两个不同的内存位置,我如何在这里应用重叠概念?
解决方法
您的代码调用了未定义的行为,strcpy
的目标缓冲区太小,无法存储源字符串。
来自strcpy
linux man page:
char *strcpy(char *dest,const char *src);
字符串不能重叠,并且目标字符串
dest
必须是 足够大,可以接收副本。当心缓冲区溢出! (看到 臭虫。)
错误部分:
如果
strcpy()
的目标字符串不够大,则 一切都会发生。固定长度字符串缓冲区的溢出是 最喜欢的饼干技术,可以完全控制 机器。
C标准建立了未定义行为的概念,如下所示:
C11 N1570草案§3.4.3
未定义的行为
使用非便携式或错误程序构造或错误数据的行为,对此国际标准不施加任何要求。
注意
可能的不确定行为范围从完全忽略具有不可预测结果的情况到在翻译或程序执行过程中以环境特征的书面方式记录的行为(带有或不带有诊断消息)到终止翻译或执行(带有诊断消息)。
示例
未定义行为的一个示例是整数溢出时的行为。
这就是程序中发生的事情,其结果是完全不确定的,根据未定义行为的定义,没有任何解释,只有对特定构建的生成程序集进行分析才能了解正在发生的情况
正如您在this online compilation中所看到的那样,三种不同的编译器以不同的方式处理此问题,并且与本地编译器相比也有所不同,但与在崩溃前产生预期输出的本地生成方式有所不同。 / p>