下面的执行结果是什么?

#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. 移动端js插件分享

    分享几个移动端使用的插件,个人感觉挺不错的. 1. TouchSlide1.1 滑动的焦点图  http://pan.baidu.com/s/1i3J6bbB 2. iscroll.js  模拟滚动条 ...

  2. js创建对象的几种常用方式小结

    第一种模式:工厂方式  var lev=function(){ return "666"; }; function Parent(){ var Child = new Object ...

  3. B2C 电商网站需要怎样的 ERP 系统

    B2C 电商网站需要怎样的 ERP 系统 主要由如下一些系统组成:1.进销存系统,你的产品的采供销当然最好是由系统来实现:2.BI系统,BI包括所有的流量.订单.商品.库存.发货等所有数据节点,亦包含 ...

  4. Linux 内核无线子系统

    Linux 内核无线子系统 浅谈 Linux 内核无线子系统 Table of Contents 1. 全局概览 2. 模块间接口 3. 数据路径与管理路径 4. 数据包是如何被发送? 5. 谈谈管理 ...

  5. MRP工作台任务下达之计划组为必输

    应用 Oracle   Manufacturing Planning 层 Level Function 函数名 Funcgtion Name MRPFPPWB 表单名 Form   Name MRPS ...

  6. logrotate 日志清理后 rsyslog中断问题

    <pre name="code" class="html">随后配置logrotate的配置文件/etc/logrotate.conf,加入下面的内 ...

  7. NOI2011 Day2

    NOI2011 Day2 道路修建 题目描述:给出一棵树,求每条边的两边的端点数的差乘边权之和. solution: 题目可能描述得不太清楚,如图: 对于虚边,如果边权为10,两边的端点数之差为2,这 ...

  8. oracle中文支持

  9. oracle重新启动步骤

    1. 停应用层的各种程序. $lsnrctl stop   3. 在独占的系统用户下,备份控制文件: SQL>alter database backup controlfile to trace ...

  10. 数学之路-python计算实战(13)-机器视觉-图像增强

    指数变换的基本表达式为:y=bc(x-a)-1 当中參数b.c控制曲线的变换形状,參数a控制曲线的位置. 指数变换的作用是扩展图像的高灰度级.压缩低灰度级.能够用于亮度过高的图像 本博客全部内容是原创 ...