自己的理解:堆,栈及变量在内存中的分布

来源:互联网 发布:vb automation 编辑:程序博客网 时间:2024/05/16 23:57

参考文章:http://www.cppblog.com/oosky/archive/2006/01/21/2958.html

下文部分是参考的,主要写博客,是为了更好的让自己理解,巩固知识点。日积月累。

堆,栈及变量在内存中的分布

1.

      由程序员自己申请和释放内部是不连续的链式结构。

      C语言中,malloc就是用来从堆中申请内存的;C++中,new是用来申请内存的。

2.

    由编译器内部申请释放的内存空间。有固定大小。

3.其他知识点

    一个由C/C++编译的程序,其内存主要分为:

   a).堆区:malloc,new等申请的内存,自己申请,自己释放。free,delete.

   b).栈区:局部变量(函数内部的变量以及函数的参数)

   c).全局变量区:全局变量和静态变量分布的地方。初始化的全局变量和静态变量是放在一块的,未初始化的全局变量和静态变量是放在相邻的另一块区域内。

   d).文字常量区:常量字符串放在这儿。程序结束系统自动回收。

       比如:char array[] = "abcdefg";//abcdefg/0是放在文字常量区的

   e).程序代码区: 存放函数体的二进制代码。

4.经典例子:

    int a = 0;//全局变量-----在全局变量区(初始化区域)

   char* p1;//全局变量-----在全局变量区(未初始化区域)

   void main()

  {

         char* p2;//局部变量----在栈区

         char[] p3 = "abcd";//在文字常量区

         char* p4 = "efg";//p4在栈区,efg/0在文字常量区

         static int b = 4;//静态变量-----在全局变量区(初始化区域)

         static int c;//????此处c如果不初始化,默认为??待会测试下!!!----在未初始化的全局变量区------------刚刚测试了下,为 0

         p1 = malloc(10);//在堆区

         p2 = malloc(10);//在堆区

  }

5.附加部分:C语言中变量在内存中是如何分布的?

       在C语言中,变量可以分为全局变量,局部变量,静态变量,寄存器变量。其中寄存器变量起提示作用,不要取地址。如:register a = 5;printf("%d",&a);

     看下面的例子:

     int g1=0, g2=0, g3=0;

     void main()

    {

           static int s1=0, s2=0, s3=0;

           int v1=0, v2=0, v3=0;


           printf("0x%08x/n",&g1);
           printf("0x%08x/n",&g2);
           printf("0x%08x/n",&g1);

           printf("0x%08x/n",&s1);
           printf("0x%08x/n",&s2);
           printf("0x%08x/n",&s3);

           printf("0x%08x/n",&v1);
           printf("0x%08x/n",&v2);
           printf("0x%08x/n",&v3);

         

    }

     0x004174c4
     0x004174c8
     0x004174c4


     0x004174d0
     0x004174d4
     0x004174d8

 

     0x0012ff60
     0x0012ff54
     0x0012ff48

     

由此可以看出,全局变量和静态变量在内存中在同一块区域的,而局部变量与之相差十万八千里。

6.再看一个例子

   void fun1(int param1,int param2,int param3)
{
    int v1 = param1;
    int v2 = param2;
    int v3 = param3;

    printf("0x%08x/n",&param1);
    printf("0x%08x/n",&param2);
    printf("0x%08x/n",&param3);

    printf("0x%08x/n",&v1);
    printf("0x%08x/n",&v2);
    printf("0x%08x/n",&v3);
        //0x0012fe6c
        //0x0012fe70
        //0x0012fe74
        //0x0012fe5c
        //0x0012fe50
        //0x0012fe44
}

void main()

{

   fun1(1,2,3);

}

对于这个例子,可以看出对于函数参数是由从右向左压入栈的,先压入param3,再压入param2,最后压入param1,根据“先进后出”原理,param3的地址>param2的地址>param1的地址。

而对于下面的局部变量,可以看出先压入V1,然后V2,最后V3.

而函数参数比局部变量更早的压入栈区。

 

以上代码编译环境:windowXP + VS08;

以上可能有错误,望指正。

原创粉丝点击