前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大神洗礼第二讲——内存对齐相关

大神洗礼第二讲——内存对齐相关

作者头像
Linux云计算网络
发布2018-01-10 18:47:35
7440
发布2018-01-10 18:47:35
举报
文章被收录于专栏:Linux云计算网络Linux云计算网络

Author:bakari       Date:2012.10.22

主要内容:内存对齐相关

1、 温故而知新:防御性编程的应用

防御性编程的详细讲解可见我的另一篇文章:https://cloud.tencent.com/developer/article/1017817

string函数原型的详解可见我的“string函数系列之”的文章:https://cloud.tencent.com/developer/article/1017805

< 1 >、strlen函数:无局部变量,递归调用

代码语言:javascript
复制
1 size_t myStrlen(const char * Str)  //递归调用
2  {
3      assert(NULL != Str);
4      if ('\0' == * Str)
5          return 0;
6      else
7          return (myStrlen(Str + 1) + 1);
8  }
9  

< 2 >、strlen函数:含局部变量

代码语言:javascript
复制
 1 size_t myStrlen(const char * Str)  //常规方式:返回长度
 2  {
 3      assert(NULL != Str);
 4      size_t nLen = 0;
 5      while ('\0' != * Str ++)
 6          nLen ++;
 7      
 8      return nLen;
 9  }
10  
代码语言:javascript
复制
1 size_t myStrlen(const char * Str)  //常规方式:返回地址的差值
2  {
3      assert(NULL != Str);
4      const char * tempStr = Str;
5      while('\0' != * ( ++ Str ) ); //note!
6  
7      return (Str - tempStr);
8  }
9  

 < 3 >、strcpy函数原型

代码语言:javascript
复制
 1 void myStrcpy(char * strDestination, const char * strSource) //strcpy()
 2  {
 3      assert(NULL != strDestination);
 4      assert(NULL != strSource);
 5      while ('\0' != * strSource)
 6          * strDestination ++ = * strSource ++;
 7  
 8      * strDestination = '\0';  //key!
 9  }
10  

<4>、memcpy函数原型 

代码语言:javascript
复制
 1 void * myMemcpy(void * strDestination, const void * strSource, size_t n) //memcpy()
 2  {
 3      assert(NULL != strDestination);
 4      assert(NULL != strSource);
 5      char * strD = (char *)strDestination;
 6      char * strS = (char *)strSource;
 7  
 8      while ( '\0' != * (char *) strSource && n -- ) 
 9          * strD ++ = * strS ++;
10      * strD = '\0';
11      return strDestination;
12  }
13  

2、不同数据在内存中的存储

这一部分在我的另外一篇文章有详细的讲解:http://www.cnblogs.com/bakari/archive/2012/08/05/2623637.html

全局/静态数据区:存储全局变量、全局静态变量、局部静态变量。

常量数据区:存储常量字符串,字符串常量存储的区域不可修改。

代码区:存储程序代码。 栈区:存储自动变量或局部变量,函数参数等。

堆区:是由用户程序控制的存储区,存储动态产生的数据,通过new或malloc获得的内存是堆得内存。

这是分大类,细分的话还有初始化数据区和非初始化数据区等等。

见下面的图:

下面是linux进程内存布局,4G的内存分配1G给内核使用,用户地址空间又细分成上面图示的分布。

如上图,内存区的堆和栈是动态增长和缩减的,堆是从未初始化数据区开始,向上动态增长,增长过程中虚拟地址值变大;而栈则从高地址向下端动态增长,虚拟地址值变小。 DATA(初始化数据区)和BSS(未初始化数据区)有一些值得注意的问题:

DATA区存放着在编译期就已确定的变量,这些初始变量值保存在最终生成的二进制文件中,并在程序运行时原封不动地将这些值映射到进程的初始化数据区。也就是二进制文件所存储变量的空间大小和进程虚拟地址空间一样大。

BSS区存储那些未被初始化的变量,在程序启动时,这些变量都被初始化为0,和DATA区不同,在最终生成的二进制文件中,不是存储着每一个变量的大小值,而是用一个记录值来记录空间的总大小。(E.g:有150KB的未初始化数据的大小,用一个4字节的空间来记录,值记为:150KB * 1024),但在进程虚拟地址空间中必须开辟出150KB的大小的空间来记录每一个值(值为0)。

3、 不同数据在内存中的存储

< 1 >、自定义数据类型

简单说:就是指由若干标准数据类型组成的一种复合类型,也叫记录类型。

定义方式: Type 自定义类型名

        元素名[(下标)] As 类型名      

            ……     

        元素名[(下标)] As 类型名

 End Type

元素名:表示自定义类型中的一个成员。

下标:表示是数组。

类型名:为标准类型。

注意:

<1> 自定义类型一般在标准模块(.bas)中定义,默认是Public

<2> 自定义类型中的元素可以是字符串,但应是定长字符串

<3> 不可把自定义类型名与该类型的变量名混淆

<4> 注意自定义类型变量与数组的差别:它们都由若干元素组成,前者的元素代表不同性质、不同类型的数据 像struct, union, enum就是三种比较常用的自定义数据类型。

 < 2 >、数据对齐

这一部分在我的另外一篇文章也有详细的讲解:https://cloud.tencent.com/developer/article/1017819

i、 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。

ii、 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

iii、 性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

4、 复杂声明:

所用方法:右左法则

对于右左法则的详细讲解在我的另外一篇文章也有详细的讲解:https://cloud.tencent.com/developer/article/1017820

int (*p)[10]; p是一个指向10个int型元素的数组指针。

int *(*func())() ; func是一个指向无参函数的函数指针,函数返回值也是一个指向另外一个函数的函数指针,该函数的返回值是int型变量。

char (*(*x[3])())[5]; 非法,原因是函数的返回值是一个具有5个int元素数组。C语言规定不能返回数组。

char (*(*x())[])(); 非法,原因是数组的元素是函数。这样不能保证函数的类型一致。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2012-10-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档