vs2008教程中为什么使用strcpy不安全而用strcpy_s替换(尽量详细点)

strcpy_s是strcpy的安全版本,它之所以安全,是因为其在拷贝字符串的时候会有越界的检查工作。以下是strcpy_s的实现代码,在tcscpy_s.inl文件可以找到:
*tcscpy_s.inl - general implementation of _tcscpy_s
Copyright (c) Microsoft Corporation. All rights reserved.
This file contains the general algorithm for strcpy_s and its variants.
_FUNC_PROLOGUE
errno_t __cdecl _FUNC_NAME(_CHAR *_DEST, size_t _SIZE, const _CHAR *_SRC)
/* validation section */
_VALIDATE_STRING(_DEST, _SIZE);
_VALIDATE_POINTER_RESET_STRING(_SRC, _DEST, _SIZE);
p = _DEST;
available = _SIZE;
while ((*p++ = *_SRC++) != 0 && --available & 0)
if (available == 0)
_RESET_STRING(_DEST, _SIZE);
_RETURN_BUFFER_TOO_SMALL(_DEST, _SIZE);
_FILL_STRING(_DEST, _SIZE, _SIZE - available + 1);
_RETURN_NO_ERROR;
_VALIDATE_STRING应该是验证字符串的合法性,是否以null结尾。
_VALIDATE_POINTER_RESET_STRING应该是记录字符串的原始信息,以便拷贝失败以后恢复。
当目的地空间不够时,会根据_VALIDATE_POINTER_RESET_STRING记录的信息恢复字符串,并且(在Debug模式下)以弹出对话框的形式报告错误。
_FILL_STRING完成在字符串最后加上null结束符的工作。以前没有注意到这一点,所以犯了一个以下的错误,先看源代码:
const int ALLOC_GRANULARITY = 64 * 1024; //分配粒度:64K
//随机产生一个指定范围内的随机数
inline int RandomGen(int nMin, int nMax)
return (rand() % (nMax - nMin + 1) + nMin);
int _tmain(int argc, _TCHAR* argv[])
srand((unsigned)time(NULL));
char *pBuf = new char[ALLOC_GRANULARITY];
//读取500个单词到vector
vector&string& vecW
//存放单词的vector
//省略读取F:\\hp1.txt文件中的单词并存放在vector中的代码。。。。
//fill the buffer
char *p = pB
str = vecWord[RandomGen(0, nWordNum-1)];
//get a string from the vector randomly
while ((p+str.length()) & pBuf + ALLOC_GRANULARITY)
//copy string into the buffer
strcpy_s(p, str.length()+1, str.c_str());
//set pointer p to the end of the string
p += str.length();
//把单词最后一个null符号用空格覆盖,然后指针前移,否则会导致pBuf指向的字符串始终是第一个得到的字符串
*p++ = ' ';
str = vecWord[RandomGen(0, nWordNum-1)]; //get a string from the vector randomly
vecWord.clear();
//省略写文件的代码。。。。
以上需要的地方有如下几点:
1. string::c_str()返回的const char*是包含null结束符的,所以在使用strcpy_s需要在第二个参数指定缓冲区大小的时候加上1,因为string::length()返回的长度是不包括null结束符的
2. 要把每个单词都保存进pBuf中,还需要把每个单词的null结束符先覆盖掉,否则从pBuf读取字符串的时候只会读取到第一个存入的单词。所以这两行代码很重要:
//set pointer p to the end of the string
p += str.length();
//把单词最后一个null符号用空格覆盖,然后指针前移,否则会导致pBuf指向的字符串始终是第一个得到的字符串
*p++ = ' ';
阅读(...) 评论()关闭visual&studio关于strcpy一类函数的安全报警
strcpy(...);
strcat(...);
strcat(...);
sprintf(...);
这一系列函数,在visual studio
2013中使用时会报error,之前都是warning如:'strcpy':
This function or variable may be
using strcpy_s
instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See
online help
for details.
除了网上提供的一般方法外(例如:将不安全接口改为安全接口,将strcpy改为strcpy_s等;将_CRT_SECURE_NO_WARNINGS关掉),my哈尼说这样就把所有的安全警告都关掉了,不太好,于是他在我的代码里加入#pragma
warning(disable:4996)这样一句话,就针对性的把这种报警关掉了。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。2242人阅读
//C++中使用strcpy的问题:
#include&iostream&
#include&cstring&
class Student{
Student(char *name1, char *stu_no1, float score1);
~Student();
void disp();
char *stu_
Student::Student(char *name1, char *stu_no1, float score1){
name = new char[strlen(name1) + 1];
strcpy(name, name1);
stu_no = new char[strlen(stu_no1) + 1];
strcpy(stu_no, stu_no1);
score = score1;
Student::~Student(){
delete []stu_
void Student::disp(){
cout && &name: & && name &&
cout && &stu_no: & && stu_no &&
cout && &score: & && score &&
int main(){
Student stu1(&Li ming&, &&, 90);
stu1.disp();
Student stu2(&Wang fang&, &&, 85);
stu2.disp();
报错:warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
See online help for details.
1)根据warning,第一个方法,该strcpy为strcpy_s
strcpy_s定义:
errno_t __cdecl strcpy_s(_Out_writes_z_(_SizeInBytes) char * _Dst, _In_ rsize_t _SizeInBytes, _In_z_ const char * _Src);
注意strcpy_s中多了第二个参数,限制复制字符串的长度,避免越界。
微软的警告,主要因为那些C库的函数,很多函数内部是不进行参数检测的(包括越界类的),微软担心使用这些会造成内存异常,所以就改写了同样功能的函数,改写了的函数进行了参数的检测,使用这些新的函数会更安全和便捷。关于这些改写的函数你不用专门去记忆,因为编译器对于每个函数在给出警告时,都会告诉你相应的安全函数,查看警告信息就可以获知,在使用时也再查看一下MSDN详细了解。
本例中,修改代码为:
Student::Student(char *name1, char *stu_no1, float score1){
name = new char[strlen(name1) + 1];
strcpy_s(name, strlen(name1) + 1, name1);
stu_no = new char[strlen(stu_no1) + 1];
strcpy_s(stu_no, strlen(stu_no1) + 1, stu_no1);
score = score1;
2)根据warning,第二个方法,To disable deprecation, us _CRT_SCURE_NO_WARNINGS. 找到项目--属性--配置属性--C/C++--命令行--其它选项 中填上【&/D &_CRT_SECURE_NO_DEPRECATE&】(注:中括号中的全部内容)。
或者 在源程序一开始 加上
#pragma warning(disable : 4996)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:11642次
排名:千里之外
(1)(2)(2)(2)(1)(1)有关c++ vs2013编译器中strcpy_s函数的一个小问题。帮我看看那里出错。_百度知道
有关c++ vs2013编译器中strcpy_s函数的一个小问题。帮我看看那里出错。
gelin&quot://g; & & if (str == NULL)&nbsp.m_ &nbsp.&nbsp://g;&#include& &nbsp.m_else&}结果本来应该是gelintingting的;p = NULL; strcpy_s(p;m_size = 0。<img class="ikqb_img" src=" else& &nbsp.p = new char[str1;iostream& &nbsp,str1; &/zhidao/wh%3D600%2C800/sign=e7c7d287b33533faf5e39b/96dda144adbe1b0ef431adcbef841d.jpg" esrc="http, s2(&quot
提问者采纳
&m_size&1;1]:print(){&nbsp,这个大小不包括最后的结束符.p&char&mystring&amp,m_size+1;&{&&&{&p&str1:#include&str1;new&new&&str){&=&m_size&//&&nbsp,包括了结束符;mystring(const&//&p&nbsp,要包括最后的结束符&mystring&=&nbsp:;1234&quot,&NULL)&&&&NULL;mystring&p&}:&}void&&m_size&&赋值的字符数是m_size+1;&&nbsp.m_size&p&class&char[m_size&nbsp,&NULL)&);0;1];str){&1];if&nbsp.m_size,导致strcpy_s函数使用失败你的错误在于=操作符的重载;=&&+&p);&nbsp.m_size&}void&{&&strcpy_s(str1;(str&string&1;):operator&strcpy_s(p;&else&print();using&&iostream&&*&+&&nbsp.p),m_size&s2,&int&m_&s3;new&str){&}}=&namespace&nbsp,&nbsp,&main(){&mystring&=&&&&char[str1;+&=&&&{&nbsp:mystring(char&=&+&nbsp,&nbsp:mystring(const&=&str);m_}void&mystring&(mystring&nbsp,但是;&&s1(&&*p;cout&//&&nbsp,即用str给this所指向的cstring类对象赋值;+&);char[m_size&nbsp:;&&&if&m_size&s3&strcpy_s(p;}&new&nbsp,类成员m_size的记录的到底是什么;(mystring&&+&str);+&+&nbsp你定义了这个类;s3;mystring。void operator=(cstring str){}隐含的操作数this是左操作数;&str1;(str,&str1;m_size&//&nbsp:;&&nbsp.p;strcpy_s(str1;&&&qwer&=&p&nbsp.p&&=&==&void&&quot.p+m_=&mystring(char&&==&const&str);NULL;+&mystring&&}}mystring&nbsp,而不是给str赋值;char[m_size&//&nbsp,你搞混了修改后的代码;1];&&strlen(str);else&s2(&#include&operator=(mystring&&return&m_size&&+&1;&m_size&nbsp,你在后续的使用中;s1&nbsp.p);&=&m_size&void&&lt,&&amp:;*&=&nbsp.m_size&nbsp,&0;=&&str:operator&cout&nbsp.m_size:.m_size+1;operator+(const&str=&mystring{&nbsp,你没有弄清楚;&str);p&str)//赋值方向错了{&nbsp,看构造函数;}&nbsp,m_size记录的是字符串的大小.p).print();&strcpy_s(p
提问者评价
来自团队:
其他类似问题
为您推荐:
strcpy的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 vs2008教程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信