strcpy拷贝越界问题

来源:互联网 发布:ping 加端口号 编辑:程序博客网 时间:2024/05/02 16:49

《strcpy拷贝越界问题》

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//
//C语言标准库函数strcpy的一种典型的工业级的最简实现。
 
//返回值:目标串的地址。
 
//对于出现异常的情况ANSI-C99标准并未定义,故由实现者决定返回值,通常为NULL。
 
//参数:des为目标字符串,source为原字符串。
 
 
 
charstrcpy(char* des,const char* source)
 
{
 
  char* r=des;
   
assert((des != NULL) && (source != NULL));
 
 while((*des++ = *source++)!='\0');
 
 return r;
 
}
 
 
//while((*des++=*source++));的解释:赋值表达式返回左操作数,所以在赋值NULL后,循环停止。



一. 程序一

  1. #include<stdio.h>  
  2. #include<string.h>  
  3. void main()  
  4. {  
  5.  char s[]="123456789";  
  6.  char d[]="123";  
  7.  strcpy(d,s);  
  8.  printf("d=%s,\ns=%s",d,s);  

执行结果:

解释:

首先要解释一下,char s[]="123456789"; char d[]="123"; 这样定义的数组和变量存放在栈内存中。 
栈内存是一个自顶向下分布的数据结构,那么越先定义的变量地址就越高,越后定义的地址就越低。 
s比d定义在前,那么s得到了高地址,而d得到了相对低的地址,那么内存中的存放形式就是 
d[] <- | -> s[] 
'1' '2' '3' '\0' | '1' '2' '3' '4' '5' '6' '7' '8' '9' '\0' 
字符串拷贝后: 
'1' '2' '3' '4 ' | '5' '6' '7' '8' '9' '\0' '7' '8' '9' '\0' 
中间的‘|’表示s[]的起始位置。 
所以此时输出的是d的值是 '1' '2' '3' '4' '5' '6' '7' '8' '9' '\0's的值是 '5' '6' '7' '8' '9' '\0'

 

二. 程序二

  1. #include<stdio.h>  
  2. #include<string.h>  
  3. void main()  
  4. {  
  5.   char d[]="123";  
  6.  
  7.  char s[]="123456789";  
  8.  strcpy(d,s);  
  9.  printf("d=%s,\ns=%s",d,s);  
  10. }  

运行结果:

说明:

虽然可以看到正确的输出结果d=123456789,s=123456789执,但是产生运行错误!

这是因为字符串拷贝后,越过了目标字串的实际空间,访问到了不可预知的地址了。

三. strcpy函数原型

  1. //已知strcpy函数的原型是:  
  2. char * strcpy(char * strDest,const char * strSrc);  
  3.  
  4.  
  5. //实现代码  
  6. char * strcpy(char * strDest,const char * strSrc)  
  7. {  
  8. if ((strDest==NULL)||(strSrc==NULL))  
  9.  
  10. throw "Invalid argument(s)";   
  11.  
  12. char * strDestCopy=strDest;   
  13.  
  14. while ((*strDest++=*strSrc++)!='\0');   
  15.  
  16. return strDestCopy;  
  17. }  

 

本文出自 “技术创造人生” 博客,请务必保留此出处http://lixiaomeng.blog.51cto.com/3714496/982292

0 0
原创粉丝点击