由strcpy()函数想到的一些

来源:互联网 发布:python 前端访问数据库 编辑:程序博客网 时间:2024/04/29 12:38

题目是这样的:

下面的程序会出现何种问题?

#include<iostream>

#include<stdio.h>

int main()

{

char s[] = "123456789";

char d[] = "1234";

strcpy(d,s);

printf("%s,\n%s",d,s);

return 0;

}

刚看这个题目的时候,得出的 结果是123456789,123456789.看了好多次题目的解答都没看明白。仔细研究了一下,发现自己还是有很多问题不会的。

1、变量的内存分配

变量定义之后,要分配内存,一般情况是先定义的变量分配到高地址,后定义的分配到低地址。比如先定义s[],后定义d[],s就在高地址,d就在低地址。还有一点很重要,系统在给char[]类型分配内存的时候,是对齐的,也就是说,当给变量分配内存时,遇到不能占满整个字的,要分配给变量整个字的大小。比如,操作系统是32位的,在给变量分配内存的时候,最小的分配单位是32位,也就是4个字节。当变量占有1个字节的时候,也会给变量分配4个字节。

2、strcpy函数在拷贝的时候,要求dest的空间要足够能装下source,否则会报错。

3、在读取字符串的时候,每当遇到\0,就结束读取。

我们看一下这个题目。题目中先定义的是s,所以s在高地址,d在低地址。内存分配如下所示:

     内存地址 内容       

d   0x0030  1234      

     0x0034   \0           

s   0x0038  1234      

     0x003c   5678     

     0x0040  9\0         

当拷贝的时候,s中的内容会覆盖掉d中的内容,并且会占用s的内存,这时候系统是不会报错的,因为s的内存已经分配。拷贝后结果如下:

     内存地址 内容       

d   0x0030  1234      

     0x0034   5678           

s   0x0038  9\034      

     0x003c   5678     

     0x0040  9\0  

最后打印的结果为s:9,d:123456789.

如果定义的顺序相反,内存分配结果如下:

     内存地址 内容 

s   0x0030  1234      

     0x0034   5678           

     0x0038  9\0      

d   0x003c  1234     

     0x0040  \0  

当拷贝的时候,就出现问题了,因为s要覆盖掉d中的内容,但是,d的空间不够,拷贝的时候,使用到了没有分配的空间,这时候会出现问题。在vs6.0中运行时,会输出s:123456789,d:123456789同时会提示错误。

知道以上说的三点,这个题目就很容易解决了。

原创粉丝点击