static const等类型在内存中的分配

来源:互联网 发布:软件设计师中级考试 编辑:程序博客网 时间:2024/06/04 20:58

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


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

     2:DATA       存放常量字符串

     3:CODE      代码

     4:Heap     

     5:  Stack

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

2: 看几个例子:

view plaincopy to clipboardprint?
int a = 10; //BBS区  
main()  
{  
     int a1 = 10;              //stack  
       
     static int a2 = 10;       //a2在BBS上。  
       
     char* a3  = new cha[3];   //a3在栈上,分的控件在heap上。  
      char a4[] = "abc"        //a4 和“abc”均在stack上!  
      char *a5   = "abd";      //a5在栈上, "abd"在DATA上。  

int a = 10; //BBS区
main()
{
     int a1 = 10;              //stack
    
     static int a2 = 10;       //a2在BBS上。
    
     char* a3  = new cha[3];   //a3在栈上,分的控件在heap上。
      char a4[] = "abc"        //a4 和“abc”均在stack上!
      char *a5   = "abd";      //a5在栈上, "abd"在DATA上。
}

  上边比较让人难理解的是最后两个,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编译时是认为其有地址的!  这是两种截然不同的处理方式,前者叫:内链接 后者叫:外连接!

        view plaincopy to clipboardprint?
const int a = 5;  
int array[a]; 
const int a = 5;
int array[a];

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

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

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

总结一下const:

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

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

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

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

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

 

本文来自CSDN博客,出处:http://blog.csdn.net/NRC_DouNingBo/archive/2010/09/16/5889154.aspx

 

原创粉丝点击