strcpy(char* dest, const char *src)函数参数问题

找点资料真费劲 2013-06-27 02:50:25
不是说strcpy(char* dest, const char *src)函数参数
src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串
在VC下运行这两个为什么通过了啊?
char dest1[4]="aaa";
char src1[6]="bbbbb";
strcpy(dest1,src1);
cout<<dest1<<endl;
输出bbbbb

char dest2[4]="aaa";
char* src2="bbbbb";
strcpy(dest2,src2);
cout<<dest2<<endl;
输出bbbbb

//而这两个居然崩了
char* dest3="aaaaa";
char src3[4]="bbb";
strcpy(dest3,src3);
cout<<dest3<<endl;

char* dest4="aaaaa";
char* src4="bbb";
strcpy(dest4,src4);
cout<<dest4<<endl;
求指点!!!
...全文
431 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lihevvv 2013-06-28
  • 打赏
  • 举报
回复
char* dest3="aaaaa" "aaaaa"是常量,dest3指向常量区,修改必出错。 char dest1[4]="aaa"; char src1[6]="bbbbb"; 这个是溢出,虽然这次不出错,但不保证下次不出错,危险性极大。
lm_whales 2013-06-28
  • 打赏
  • 举报
回复
不是说strcpy(char* dest, const char *src)函数参数 src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串 在VC下运行这两个为什么通过了啊? 这是指的下面这种情况: char a[]="abcdef ghijk"; char *b=a+4; strcpy(b,a); strcpy(a,b); 这种情况,也是运行错误,也是一种逻辑错误。 这两种情况是不能保证,得出正确结果的!! 和你举的例子,有所不同,这里的拷贝是合法的,但是结果是错误的,或者有可能是错误的。 PS: 这是因为,strcpy处理的,是两个不同数组之间的,数据复制; 而这里,使用strcpy,已经改变了strcpy的语义了,成了同一数组的内部的数据复制了。 这种情况,责任不在编写strcpy函数的人,而在于使用strcpy函数的人。 这个函数,明显不是干这个事情的,这是对函数strcpy的误用!! 至于你那个例子,原因上面已经说的很清楚了,这里不再赘述了!
lm_whales 2013-06-28
  • 打赏
  • 举报
回复
发表于: 2013-06-27 14:50:25 不是说strcpy(char* dest, const char *src)函数参数 src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串 在VC下运行这两个为什么通过了啊?

//1)
 char dest1[4]="aaa";
 char src1[6]="bbbbb";
 strcpy(dest1,src1); 
 cout<<dest1<<endl;
// 输出bbbbb
// 这个已经出错了,编译器没有报错,这是逻辑错误,你在4个字节的内存里放了6个数据,C,C++
// 是允许的,不过别人不会放过你的,你用了别的内存了。
// 如果你的程序,还要用到,dest1后面2字节的内存中存放的数据,那么对不起,这个数据被
// strcpy(dest1,src1);修改了,不是原来的那个值了,会出现想破脑袋,都想不明白的错误!!!!!

//2)
 char dest2[4]="aaa";
 char* src2="bbbbb";
 strcpy(dest2,src2);
 cout<<dest2<<endl;
// 输出bbbbb, 
// 这个和第一个一样,这两种写法的区别是,src2是个指针,占用四sizeof( char*)大小的内存,
//"bbbbb"这个常量另外存储,占用6个字节即字符串;
//即"bbbbb"的长度5加上结束符'\0'的长度一个字节的内存。
//指针src2的值是,存储"bbbbb"的内存的首地址,多占用一个指针长度的内存。

//src1是个数组,常量"bbbbb";就存储在src1中,数组首地址就是常量 "bbbbb",占用的内存;
//数组名src1,这个指针常量的值,是数组首地址。数组名src1不占用内存,这个数组占用6个字节的内存;
//这个数组用常量初始化,但数组不是常量,数组名是个指针常量。


 //而这两个居然崩了
//3) 
 char* dest3="aaaaa";
 char  src3[4]="bbb";
 strcpy(dest3,src3);// 数据拷到常量中,编译器暗地里使坏!
                    // 表面允许,编译可以通过,暗地里使绊子,运行时出错!
                    // 用字符常量初始化指针,常量数据放到常量区,不可写,写出错!
 cout<<dest3<<endl;
//char* dest3,从使用上看,是指向常量字符串的指针,但是这是一个字符串指针,不是常量字符串指针,
//而且这个指针本身也不是常量,所以 strcpy(dest3,src3);编译可以通过,不过"aaaaa";是常量;
//编译器可以把它存储在常量区,这里用常量字符串,初始化非常量指针,
//有人说,这是为了和C兼容,而留下的口子,如果严格执行类型检查的话,编译应该不能通过才对!!!
//
//不过用常量指针初始化非常量指针,应该是比较正常的行为吧,因为可以用常量初始化非常量的。
//如果只能用变量给变量赋值,那是任何一门编程语言也做不到的。
//

//4)
 char* dest4="aaaaa";
 char* src4="bbb";
 strcpy(dest4,src4);
 cout<<dest4<<endl;
// 求指点!!!
//这和第三个一模一样,不过两个指针,都是用常量字符串,初始化罢了!!!
不会上网 2013-06-27
  • 打赏
  • 举报
回复
如果我没记错的话: char dest1[4] = "aaa";中的 dest1是变量,然后赋值为aaa。 char* dest2="aaa"; 中的dest2是指针,指向的是常量。 aaa 在编译时是编译在数据块里面的。 dest2是直接指向数据块里面的数据,而dest1是栈里面分配的空间所以是可以改变的。 strcpy 复制的src1 的长度大于dest1的长度没有出问题,仅仅只是巧合而已。只能证明dest1后面有足够的空间没有使用,这种写法是有弊端的尽量加上判断,或者你很清楚长度关系。
hugett 2013-06-27
  • 打赏
  • 举报
回复
dest3跟dest4指向的是字符串常量。。
赵4老师 2013-06-27
  • 打赏
  • 举报
回复
其实电脑开机后物理内存的每个字节都是可读写的,区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。
橡木疙瘩 2013-06-27
  • 打赏
  • 举报
回复
我已经说的,前两个是问题没有表现出来。buffer overload不一定就表现崩溃,还有用这种行为了传播病毒的呢。 后两种中char* dest3="aaaaa"就已经错了,"aaaaa"是只读的,应该给char const *。
  • 打赏
  • 举报
回复
前两个我认为应该出错是因为src占的空间比dest所占空间大,他居然没出错??? 后两个不清楚错在哪里?? 有没有清晰点的解释啊??? 是不是程序员都不用这种函数了??
橡木疙瘩 2013-06-27
  • 打赏
  • 举报
回复
char* dest3="aaaaa"; char* dest4="aaaaa"; 都是VC惹的祸。 "abcdef"这一类的字符串字面量只能赋值给char const *类型指针,不能赋值给char *类型。 如果你把dest3和dest4定义为char const * ,编译器就会阻止你调用strcpy。 没出问题那两个,只是问题没有表现出来、。

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧