strcpy()是依据源串的/0作为结束判断的,不检查copy先的Buffer的Size,如果目标空间不够,就有会出现缓冲区溢出问题。
类似这样的函数还有:
字符串拷贝函数:strcpy, wcscpy
字符串拼接函数:strcat, wcscat
字符串格式化输出函数:sprintf, swprintf, vsprintf, vswprintf,
字符串格式化输入函数:scanf, wscanf, sscanf, swscanf, fscanf, vfscanf, vscanf, vsscanf
stdin流输入函数:gets
这类函数是公认的危险函数,应禁止使用此类函数(微软从Windows Vista的开发开始就全面禁用了危险API)。
解决的办法就是使用strncpy_s()、strcpy_s()、strncpy()等不同环境而准备的安全度很高的函数。
strcpy()
char str[]="lanzhihui is a good boy!";//假设len=strlen(str)
char str_1[25];
//测试strcpy()
memset(str_1,0,sizeof(str_1));
strcpy(str_1,str);//当数组大小 小于等于 len时,会发生缓冲区溢出,程序崩溃
//当数组大小 大于等于 len+1时,才能正确运行,并且数组尾部为'\0'
puts(str_1);
strncpy()
char str[]="lanzhihui is a good boy!";//假设len=strlen(str)
char str_1[25];
//测试strncpy()
memset(str_1,0,sizeof(str_1));
strncpy(str_1,str,sizeof(str_1));//当数组大小 小于等于 len时,也会发生缓冲区溢出,但是程序不会崩溃,发生缓冲区溢出是因为数组没有以'\0'结束,或者说截断超出长度限制的字符串,包括源字符串结尾的’\0’。
//当数组大小 大于等于 len+1时,才能正确运行,并且数组尾部为'\0'
str_1[sizeof(str_1)-1]='\0';//上面问题:缓冲区溢出可以通过数组尾部加'\0'解决
strncpy(str_1,str,sizeof(str_1)-1);//本句正确使用strncpy,不会造成缓冲区溢出,并且在数组最后加入了'\0'。
puts(str_1);
strcpy_s()
//测试strcpy_s
memset(str_1,0,sizeof(str_1));
strcpy_s(str_1,str);//strcpy_s必须完全拷贝源串(假如第二个参数小于源串,会导致运行出错),所以第二个参数可有可无,若只想拷贝一部分源串则应该用strncpy_s函数
//只有当数组大小 大于等于 len+1时,才能正确运行,并且数组尾部为'\0'。
puts(str_1);