zoukankan      html  css  js  c++  java
  • 大神洗礼第二讲——内存对齐相关

    Author:bakari       Date:2012.10.22

    主要内容:内存对齐相关

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

    防御性编程的详细讲解可见我的另一篇文章:http://www.cnblogs.com/bakari/archive/2012/08/27/2658215.html

    string函数原型的详解可见我的“string函数系列之”的文章:http://www.cnblogs.com/bakari/archive/2012/08/09/string%E5%BA%93%E5%87%BD%E6%95%B0.html

     

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

    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函数:含局部变量

     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  
    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函数原型

     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函数原型 

     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 >、数据对齐

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

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

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

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

     

    4、 复杂声明:

    所用方法:右左法则

    对于右左法则的详细讲解在我的另外一篇文章也有详细的讲解:http://www.cnblogs.com/bakari/archive/2012/08/28/2659889.html

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

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

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

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

    stay hungry stay foolish ----jobs 希望多多烧香!
  • 相关阅读:
    img src 改变问题
    <a href="javascript:;" ></a>
    CSS先后顺序影响效果
    CSS学习遇到问题,注释问题
    关于某个网站的分析
    问题汇总
    作为一枚web前端开发工程师 这些CSS 小技巧你值得掌握
    web前端性能优化
    Sea.js学习笔记
    学习计划
  • 原文地址:https://www.cnblogs.com/bakari/p/2734772.html
Copyright © 2011-2022 走看看