strcpy/strncpy/strcpy_s比较
转载自:http://blog.csdn.net/caomiao2006/article/details/4766416
strcpy()是依据源串的/0作为结束判断的,不检查copy先的Buffer的Size,如果目标空间不够,就有BufferOverflow问题。请务必使用按照strncpy_s()、strcpy_s()、strncpy()等不同环境而准备的安全度很高的函数。
strcpy函数,就象gets函数一样,它没有方法来保证有效的缓冲区尺寸,所以它只能假定缓冲足够大来容纳要拷贝的字符串。在程序运行时,这将导致不可预料的行为。
另外、即使是使用安全度很高的函数,由于用法方面的原因,也可能发生Buffer Overflow,请注意如下几点。不要在strcpy_s()、strncpy_s()进行Buffer Size的誤指定。
strcpy_s()两个参数和三个参数的不同用法区别如下代码所示:
- char *str1=NULL;
- str1=new char[20];
- char str[7];
- strcpy_s(str1,20,"hello world");//三个参数
- strcpy_s(str,"hello");//两个参数但如果:char *str=new char[7];会出错:提示不支持两个参数
第二个参数表示目标缓冲区大小,大于或等于源串的长度+1(存放结束符/0),strcpy_s必须完全拷贝源串,若只想拷贝一部分源串则应该用strncpy_s函数。
- char * dst = (char *)malloc(10);
- //strcpy_s(dst, 10, "Hello world!");
- strncpy(dst, "Hello world!", 10);
若使用strncpy不会出错,观察内存可以发现,目标指针所指的缓冲区中完全是从源字符串拷贝过来的字符,没有/0结束符,但是若使用strcpy_s则在运行是出现断言出错,所以strncpy仍然不是安全的,因为有可能出现目标指针的字节数不足存放源指针所指向的内容。另外,若使用语句strncpy(dst, "Hello", 10);则会把剩下的空间都填充为空字符/0,带来效率问题,strcpy_s则不会。
所以从VS2005开始已经推出相应的安全版本——strcpy_s(末尾的s可能代表safe)。
接口的定义改变如下:
char* strcpy(char* dest, const char* src) --> errno_t strcpy_s(char* dest, size_t numElems, const char* src)
char* strcpy(char* dest, const char* src, size_t count) --> errno_t strcpy_s(char* dest, size_t numElems, const char* src, size_t count)
后者之所以比前者安全,是因为他们在接口增加了一个参数numElems来表明dest中的字节数,防止目标指针dest中的空间不够而导致出现Bug,同时返回值改成返回错误代码,而不是为了一些所谓的方便而返回char*。这样接口的定义就比原来安全很多。
更多关于CRT安全性修改的函数参见另一篇文章(转):VS 2005 CRT函数的安全性增强版本
strcpy/strncpy/strcpy_s比较的更多相关文章
- C语言中函数strcpy ,strncpy ,strlcpy的用法【转】
转自:http://blog.chinaunix.net/uid-20797562-id-99311.html strcpy ,strncpy ,strlcpy的用法好多人已经知道利用strncpy替 ...
- C语言中函数strcpy ,strncpy ,strlcpy的用法
strcpy ,strncpy ,strlcpy的用法 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. s ...
- C语言strcpy,strncpy和strlcpy讲解
前言 C风格的字符串处理函数有很多,如strcpy().strcat()等等. strcpy与strcat char* strcpy (char* dest, const char* src); ch ...
- C语言——常用标准输入输出函数 scanf(), printf(), gets(), puts(), getchar(), putchar(); 字符串拷贝函数 strcpy(), strncpy(), strchr(), strstr()函数用法特点
1 首先介绍几个常用到的转义符 (1) 换行符“\n”, ASCII值为10: (2) 回车符“\r”, ASCII值为13: (3) 水平制表符“\t”, ASCII值为 9 ...
- (C)strcpy ,strncpy与strlcpy
1. 背景 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 2. strcpy strcpy 是依据 /0 作为 ...
- (C)strcpy ,strncpy和strlcpy的基本用法
好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. strcpy strcpy 是依据 /0 作为结束判断的, ...
- C++ strcpy strcpy_s strncpy strlcpy
strncpy的用法:它与strcpy的不同之处就在于复制n个字符,而不是把所有字符拷贝(包括结尾'\0'). 函数原型:char * strncpy(char *dst,const char * s ...
- strcpy函数和strncpy函数的区别
strcpy函数和strncpy函数的原型介绍在我的另一篇文章中介绍了,见strcpy,strncpy,strlen等函数原型 strcpy:字串复制 原型:char *strcpy(char *de ...
- Linux C中strcpy , strncpy , strlcpy 的区别
strcpy ,strncpy ,strlcpy的用法 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. s ...
随机推荐
- Linux/Ubuntu正确卸载LXDE
第一步: sudo apt-get remove lxde 第二步 sudo apt autoremove lxde
- Python基础之用户交互、流程控制、循环语句
python的简洁性真的令人叹为观止,没有JAVA那种输入还要导个包,不学不知道,一学吓一跳啊! 我在学这些基础的时候,会把python和java.c做对比,这样更好的理解记忆! 用户交互(输入) i ...
- k8s1.9.0安装--基础集群部署
二.基础集群部署 - kubernetes-simple 1. 部署ETCD(主节点) 1.1 简介 kubernetes需要存储很多东西,像它本身的节点信息,组件信息,还有通过kubernetes运 ...
- 装饰器和"开放-封闭"原则
装饰器和"开放-封闭"原则 "开放-封闭"原则 软件开发中的"开放-封闭"原则,它规定已经实现的功能代码不应该被修改,但可以被扩展,即: 封 ...
- apache httpd多后缀解析漏洞复现
apache httpd多后缀解析漏洞复现 一.漏洞描述 Apache Httpd支持一个文件拥有多个后缀,不同的后缀执行不同的命令,也就是说当我们上传的文件中只要后缀名含有php,该文件就可以被解析 ...
- activeMQ_helloworld(一)
一.activeMQ下载,直接在Linux上wget http://mirror.bit.edu.cn/apache//activemq/5.14.5/apache-activemq-5.14.5-b ...
- php之布尔类型判断
字符串只要不为空且不为0都为true 执行结果为 执行结果为false 因为===不仅比较值,还比较类型,所以输出为false.如果使用===号比较,最好先将变量强转为bool类型,不然可能得不到想要 ...
- 最新try2hack全详解
第一题http://www.try2hack.nl/levels/: 方法:直接右键看网页源码 第二题http://www.try2hack.nl/levels/level2-xfdgnh.xhtml ...
- 【Spring】org.springframework.web.context.ContextLoaderListen 报错
详细信息如下: org.apache.catalina.core.StandardContext.listenerStart Error configuring application listene ...
- MySql数据库操作命令
数据库 database 命令 ********************************* DATABASE 创建数据库 CREATE DATABASE haodlDB DEFAULT CHA ...