几种类型的内存模型

来源:互联网 发布:js array push pop 编辑:程序博客网 时间:2024/05/09 06:24

      今天和同学同事讨论了一下static const等等类型在内存中的存储,查了若干资料,总结如下:

 

1:一个由c/c++编译的程序的内存分为以下几个部分


     1:BBS         存放全局数据和静态数据

     2:DATA       存放常量字符串

     3:CODE      代码

 

     4:Heap      

     5:  Stack

 

    这其中比较容易混淆的就是BBS与DATA区,很多人容易认为二者是一个区,实际不是的。

 

2: 看几个例子:

 

 

  上边比较让人难理解的是最后两个,a5指向的"abc"是存储在DATA上的,此时认为这个“abc”是一个常量! 而a4是一个在栈上分配的数组空间,而后边的“abc”仅仅是给其赋值用而已。

 

    而凡是static修饰的肯定是在BBS区。

 

3:上边讨论了几个比较容易理解的,还有一个不容易理解的就是const! 对于const,和朋友刚开始讨论的一个问题是:

      const  int a = 10;

      此时a是一个常量呢 还是一个大小不变的变量?  毕竟:如果是变量,则肯定不会存储在DATA中。

 

      其实平时用的const,我们依旧可以对其进行修改!只要做个不同的指针来对其进行指向,而后用这个指针来进行内容修改即可!

但是这只是一种很片面的情况,说白了吧:只要我们能拿到一块内存的地址,那我们完全可以在写代码时用这个指针来对内存进行操作,这样:编译时没有任何问题!毕竟完全复合逻辑!

 

      对于const修饰的变量,其也有全局 和 局部 之分!

      ①:当其为局部变量时:我们完全可以向平时那样用指针对其进行修改!c和c++的处理方式是一样的!亦即:此时变量是存放在栈上的!我们可以拿到地址!

      ②:当其为全局变量时:c和c++的处理方式是不一样的!c++在编译时:编译器会把这个它放到自己的符号表中!作为编译器常量!所以它是没有地址的! 而c编译时是认为其有地址的!  这是两种截然不同的处理方式,前者叫:内链接 后者叫:外连接!

         

       如上两句,如果a是一个const全局变量, 那么在c下这样写肯定是错误的!毕竟此时a为一个地址。 但是在c++下没有问题,因为编译器早把a存在符号表中作为一个常量来使用!

 

       那么对于c,既然可以取到const全局变量的地址,在后边我们依旧可以用这个地址来对其进行修改操作! 显然:这在编译的时候不会报任何错误!连warnning都没有,毕竟:完全复合逻辑! 但是运行时就会报错说:segmentation fault。这是因为:const全局变量是存放在 DATA区中的!此区受到写保护! 就算你有地址指过来也无法修改!

       而对于c++而言:显然其没有地址指向这块区域,那就谈不上后边的修改操作了,那么写肯定连编译都通过不了。

 

总结一下const:

   1:对于const局部变量,其是存放在栈上的! 可以进行修改。

   2:对于const全局变量,其是存放在DATA区的!

 

    对于c语言:编译时会采用外连接,有地址;

    对于c++预言:编译时采用内链接,没有地址,存放到符号表中作为一个常量。

   --->那么:在c中,后边如果对其进行修改,编译是没有问题的,毕竟有地址指向。但是运行出错!毕竟指向的区域不可修改!