下面的执行结果是什么?

#include<stdio.h>
#include<string.h>
void main()
{
char s[]="";
char d[]="";
strcpy(d,s);
printf("d=%s,\ns=%s",d,s);
}

执行结果:d=56789,

s=123456789

书上有关于这个的解答,说是因为当初分配的内存地址是连续内存的问题, 
原来的是1234\0123456789\0,strcpy后变成123456789\06789\0。

分析:首先要解释一下,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[]的起始位置。 
          所以此时输出的是s的值是 '5' '6' '7' '8' '9' '\0'。

这个题目出的很好,一方面考查了栈的生长方向,另一方面考查了strcpy的具体细节。

如果

char d[]="12",

char d[]="1" 答案是什么呢?

执行结果依旧是:d=56789,

s=123456789

                 '1' '2' '\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' 

这里就考虑对齐的问题,一般来说是4位一对齐。如果超过4位,就是8位一对齐。

char s[]="";
char d[]="";
printf("%p %p %p %p",d,d+,d+,d+); printf("\n%p \n",s); printf("%d\n",d[]);

运行输出:

0012FF38 0012FF39 0012FF3A 0012FF3B
0012FF3C
0 字符串结束符

Key看到d[3]是不存的。char d="12"占了4位。

如果

char d[]="1234",

char d[]="12345"

执行结果依旧是:d=9,

s=123456789

                 '1' '2' '3' ‘4’  \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'

输出:

123456789

9

看另一程序.

 

#include<stdio.h>
#include<string.h>
void main()
{
   char d[]="123";

char s[]="123456789";
strcpy(d,s);
printf("d=%s,\ns=%s",d,s);
}

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

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

参考:http://www.cnblogs.com/aquariusgx/archive/2011/02/16/1956320.html

转:一个strcpy的问题(很容易做错)的更多相关文章

  1. 自定义Jquery插件——由于项目需要,对页面中过长的文本进行截取,鼠标移上去有一个title的提示,所以做了一个Jquery过长文本处理的插件

    由于项目需要,对页面中过长的文本进行截取,鼠标移上去有一个title的提示,所以做了一个Jquery过长文本处理的插件下面是代码: // 掉用方式支持 $('select').textBeauty(1 ...

  2. 一个老牌程序员说:做Java开发,怎么可以不会这 20 种类库和 API

  3. 转一个distinct用法,很有帮助

    转一个distinct用法,很有帮助 (2011-12-01 15:18:11) 转载▼ 标签: 杂谈 分类: mysql复制 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提 ...

  4. 不到50行代码实现一个能对请求并发数做限制的通用RequestDecorator

    使用场景 在开发中,我们可能会遇到一些对异步请求数做并发量限制的场景,比如说微信小程序的request并发最多为5个,又或者我们需要做一些批量处理的工作,可是我们又不想同时对服务器发出太多请求(可能会 ...

  5. 【spring cloud】子模块module -->导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做/或者 每次导入一个新的spring boot项目,IDEA不识别子module,启动类无法启动/右下角没有蓝色图标

    如题:导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做 或者说每次导入一个新的spring boot项目,IDEA不识别,启动类无法启动,怎么解决 下面分别 ...

  6. Git库搭建好之后,当要提交一个新的文件,需要做的是3个步骤

    Git库搭建好之后,当要提交一个新的文件,需要做的是3个步骤 1.git add new.txt 2.git commit -m "add a new file" 3.git pu ...

  7. 大部分人都会做错的经典JS闭包面试题

    由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...

  8. Bug2020011601,在ssh项目的applicaitonContext.xml中,少了一个双引号,打包成功(没报错),项目运行才发现

    在ssh项目的applicaitonContext.xml中,少了一个双引号,打包成功(没报错),项目运行才发现. 加上少的双引号,解决了.

  9. 最近这两天看了关于H5游戏开发的一个教程,实践很短暂,看了很多理论的东西,现在呢也只是想回忆回忆关于EUI的部分知识吧

    首先我了解了什么是Egret: Egret中文就是白鹭的意思,Egret是一套H5游戏开发的软件.(纯粹属于个人理解) 其次我对以下几款软件的相关知识做了些了解: Egret Engine(引擎),E ...

随机推荐

  1. jquery解决onmouseover和onmouseout合用的bug问题

    经常会遇到鼠标放到一个元素上显示另外一个元素,这两个元素是父子关系,比如在A上绑定mouseover和mouseout事件来显示或隐藏B元素,A元素包含B元素,当鼠标移到B元素后浏览器认为你移开了A, ...

  2. eclipse同步远程服务器

    eclipse里有一个强大的插件,可以直接在本地编辑远程服务器代码,Eclipse Remote System Explorer (RSE) 下载安装方法: 一.下载,高版本的eclipse可以直接下 ...

  3. 程序员眼里IE浏览器是什么样的

    主流浏览器之争从上个世纪开就开始,已经持续了很长的时间.就在几年前,IE还是最主流的web浏览器.但现在形势完全不同了,人们都在笑话IE,纷纷转向其它浏览器.今天,我向大家分享一下针对IE的搞笑图片, ...

  4. Others in life

    耗电量主要是与电机有关,800W电机在48V下的工作电流大约是800/48=16.7A,因此其工作时间主要取决于电池的容量,如果电池容量是20Ah,那么大概也就连续工作1个小时左右,也就是30-40k ...

  5. MFC上下浮动与渐入渐出消息提示框实现

    类似QQ与360软件,消息提示有两种.上下浮动.渐入渐出. 1.上下浮动提示框实现 机制,定时器响应上下浮动消息. 主要API:MoveWindow. 源码如下UpDownTipDlg.h.UpDow ...

  6. [Leetcode][Python]27: Remove Element

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 27: Remove Elementhttps://oj.leetcode.c ...

  7. Servlet的运行方式

    通常我们运行servlet需要在web.xml配置文件中,注册我们写好的servlet以及其对应的访问路径. 在学习web开发中,有一种不需要配置便可以直接对servlet进行配置的方式,在web.x ...

  8. Fibonacci(数论 输出前四位Fibonacci)

    Fibonacci Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  9. Android中进行流量统计

    // ---------------------流量统计-------------------------------- try { PackageManager pm = getPackageMan ...

  10. 1.一步一步学c#(一):.NET体系结构(知识点)

    一.C#和.NET关系     1. 首先C#语言有两个很重要的方面:第一它是为了Microsoft的.NET Framework的结合而设计的,其次它是一种为问题而设计解决问题的方法的语言,它有很多 ...