转:一个strcpy的问题(很容易做错)
下面的执行结果是什么?
#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
字符串拷贝后:
这里就考虑对齐的问题,一般来说是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 ' '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的问题(很容易做错)的更多相关文章
- 自定义Jquery插件——由于项目需要,对页面中过长的文本进行截取,鼠标移上去有一个title的提示,所以做了一个Jquery过长文本处理的插件
由于项目需要,对页面中过长的文本进行截取,鼠标移上去有一个title的提示,所以做了一个Jquery过长文本处理的插件下面是代码: // 掉用方式支持 $('select').textBeauty(1 ...
- 一个老牌程序员说:做Java开发,怎么可以不会这 20 种类库和 API
- 转一个distinct用法,很有帮助
转一个distinct用法,很有帮助 (2011-12-01 15:18:11) 转载▼ 标签: 杂谈 分类: mysql复制 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提 ...
- 不到50行代码实现一个能对请求并发数做限制的通用RequestDecorator
使用场景 在开发中,我们可能会遇到一些对异步请求数做并发量限制的场景,比如说微信小程序的request并发最多为5个,又或者我们需要做一些批量处理的工作,可是我们又不想同时对服务器发出太多请求(可能会 ...
- 【spring cloud】子模块module -->导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做/或者 每次导入一个新的spring boot项目,IDEA不识别子module,启动类无法启动/右下角没有蓝色图标
如题:导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做 或者说每次导入一个新的spring boot项目,IDEA不识别,启动类无法启动,怎么解决 下面分别 ...
- Git库搭建好之后,当要提交一个新的文件,需要做的是3个步骤
Git库搭建好之后,当要提交一个新的文件,需要做的是3个步骤 1.git add new.txt 2.git commit -m "add a new file" 3.git pu ...
- 大部分人都会做错的经典JS闭包面试题
由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...
- Bug2020011601,在ssh项目的applicaitonContext.xml中,少了一个双引号,打包成功(没报错),项目运行才发现
在ssh项目的applicaitonContext.xml中,少了一个双引号,打包成功(没报错),项目运行才发现. 加上少的双引号,解决了.
- 最近这两天看了关于H5游戏开发的一个教程,实践很短暂,看了很多理论的东西,现在呢也只是想回忆回忆关于EUI的部分知识吧
首先我了解了什么是Egret: Egret中文就是白鹭的意思,Egret是一套H5游戏开发的软件.(纯粹属于个人理解) 其次我对以下几款软件的相关知识做了些了解: Egret Engine(引擎),E ...
随机推荐
- 后缀数组的一些性质----height数组
height数组:定义 height[i] = suffix[i-1] 和 suffix[i] 的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀.那么对于 j 和 k 不妨设 Rank[j] & ...
- [C#参考]Struct结构体
结构体是一种简单的用户自定义类型,也是类的一种轻量级的替代品. 相似之处:他们都有构造函数.属性.方法.字段.操作符.嵌套类型和索引器. 差异之处:类是一种引用类型,而结构体是一种值类型.因此结构体一 ...
- WebUploader IE9下报错
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.在项目中,推荐并一直在使用WebUploader进行文件上传业务开发. ...
- 【Chromium中文文档】跨进程通信 (IPC)
跨进程通信 (IPC) 转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/I ...
- windows8设置环境变量
win8,win8.1如何配置java的环境变量 工具/原料 win8,win8.1 方法/步骤 在你的计算机上右击,选择其中的属性就可以了.如下图所示. 接下来,作出如下图所示的选择. 这个 ...
- 18.java.lang.OutOfMemoryException
java.lang.OutOfMemoryException内存不足错误 当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误.
- Apache commons (Java常用工具包)简介
Apache Commons是一个非常有用的工具包,解决各种实际的通用问题,下面是一个简述表,详细信息访问http://jakarta.apache.org/commons/index.html Be ...
- delphi 基础书籍推荐
本文所推荐的书,我均仔细读过,受益良多. 1. Pascal 精要.下载Pascal精要 本书讲Pascal 语言基本知识. 2. Object Pascal 参考(中英文对照版).下载Object ...
- 简易对象垃圾回收框架 for Delphi
(一).缘起 1.1 我的一个出错程序 程序名称:呼叫处理模块的压力测试工具,分为客户端和服务端. 开发工具:Delhpi 5 相关技术:客户端通过与服务端建立Socket连接来模拟一组电话机的拨入. ...
- perl 升级到5.20版本
不建议先rm 先下载tar.gz ...然後手动安装..default 安装到/usr/local/目录下.. 然後修改/usr/bin/perl的symbolic link到/usr/local/b ...