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

    技术2025-08-18  15

    参考文章 :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;

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

    最新回复(0)