strcpy/strncpy/strcpy_s比较

 strcpy()是依据源串的/0作为结束判断的,不检查copy先的Buffer的Size,如果目标空间不够,就有BufferOverflow问题。请务必使用按照strncpy_s()、strcpy_s()、strncpy()等不同环境而准备的安全度很高的函数。

      strcpy函数,就象gets函数一样,它没有方法来保证有效的缓冲区尺寸,所以它只能假定缓冲足够大来容纳要拷贝的字符串。在程序运行时,这将导致不可预料的行为。
  另外、即使是使用安全度很高的函数,由于用法方面的原因,也可能发生Buffer Overflow,请注意如下几点。不要在strcpy_s()、strncpy_s()进行Buffer Size的误指定。

      strcpy_s()两个参数和三个参数的不同用法区别如下代码所示:

 

 view plaincopy to clipboardprint?
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];会出错:提示不支持两个参数 
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函数。


view plaincopy to clipboardprint?
char * dst = (char *)malloc(10);  
//strcpy_s(dst, 10, "Hello world!");  
strncpy(dst, "Hello world!", 10); 
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函数的安全性增强版本

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/caomiao2006/archive/2009/11/04/4766416.aspx

发布了76 篇原创文章 · 获赞 166 · 访问量 19万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章