关于程序编译后数据段、代码段、栈、堆的一些思考

来源:互联网 发布:看搞基视频男女生软件 编辑:程序博客网 时间:2024/05/21 08:51

昨天看《剑指Offer》这本书在22页说到sizeof的时候,突发奇想希望知道结构体(类)在内存上是怎么分布的。

书上说:“定义一个空的类型,用sizeof查看这个类型的大小的时候返回1(Visual Stdio),因为空类型的示例中不包含任何信息,但是当我们声明该类型的实例时,它必须在内存中占有一定的空间。”

我就在想,那如果我在类内定义成员函数,成员函数是放在哪里的呢?

带着这个问题,我写了一些代码,验证了一下几点。

1.类的成员函数,函数都是放在代码段的。

2.函数调用的时候的局部变量放到栈中。

3.main函数里的局部变量也是放到栈中。

4.main函数里的局部变量与函数调用中的局部变量不连续。(这个原因我不确定)

5.栈是向低地址增长,堆是向高地址增长。

6.类的静态变量跟全局变量放到数据段。

一些参考的东西:

数据段,代码段,堆,栈的概念

 数据段,代码段,堆,栈,概念2

一般函数指针与类的成员指针的运用


1.类的成员函数,函数都是放在代码段的。

定义类,输出类的地址,与其他变量的地址做个对比。

类函数地址与函数地址:

address of fun: fb1285
address of staticfun: fb4430
address of structHasFun::dynfun: fb12b2
address of structHasFunWithoutMem::dynfun: fb12e4
address of structHasFun::stafun: fb104b

2.函数调用的时候的局部变量放到栈中。

调用函数内的局部变量地址如下:

address of fun local variable: 22fabc
address of stafun_local: 22fabc

address of fun local variable: 22fabc
address of local variable i: 22fbb4      
address of stafun_local: 22fabc

3.main函数里的局部变量也是放到栈中。

address of local variable local_i: 22fbf0
address of local variable i: 22fbb4

4.main函数里的局部变量与函数调用中的局部变量不连续。(这个原因我不确定)

函数调用如下:

fun();stafun();printf("\n");fun();int i = 0;//在这里定义了一个变量iprintf( "address of local variable i: %x\n", &i);stafun();printf("\n");

变量的地址如下:

address of fun local variable: 22fabc
address of stafun_local: 22fabc    //这里

address of fun local variable: 22fabc
address of local variable i: 22fbb4    //与这里
address of stafun_local: 22fabc

我再调用这两个函数fun与stafun,这两个函数的局部变量地址居然是一样的。

我觉得是因为调用fun的时候,fun中的局部变量压入栈中,fun调用结束后,局部变量弹出。调用stafun时同样的道理。

但是main函数用的栈与调用fun与stafun时的栈并不是一个相同的栈,应该可以理解为main函数调用fun和stafun时产生一个子栈,来存放fun与stafun函数里的局部变量。函数返回时,子栈销毁。

5.栈是向低地址增长,堆是向高地址增长。

产生对象的顺序如下:

structHasFun stackst;structHasFun stackst1;structHasFun * pheapst = new structHasFun;structHasFun * pheapst1 = new structHasFun;
输出地址如下:

address of stackObj,stackst: 22fbe4
i's address 22fbe4


address of stackObj,stackst: 22fbd8
i's address 22fbd8


address of heapObj pheapst: 619430
i's address : 619430


address of heapObj pheapst: 619470
i's address: 619470

可见栈是向低地址增长,堆是向高地址增长。

6.类的静态变量跟全局变量放到数据段。

全局变量与类静态变量地址如下:

address of goble variable: fbf21c
si's address of static var si: fbf218


完整的代码:

#include <iostream>class structHasFunWithoutMem{public:void dynFun(){}};class structHasFun{public:int i;static int si;void dynFun(){i = 0;}/*void dynFun(int i){i = 0;}*/static void staFun(){si = 0;}};int structHasFun::si = 0;void fun(){int fun_local = 0;printf("address of fun local variable: %x\n", &fun_local);return;}static void stafun(){int stafun_local = 0;printf("address of stafun_local: %x\n", &stafun_local);return;}using namespace std;int g_i = 0;int main(){int local_i = 0;structHasFun stackst;structHasFun stackst1;structHasFun * pheapst = new structHasFun;structHasFun * pheapst1 = new structHasFun;printf( "address of goble variable: %x\n", &g_i);printf( "address of local variable local_i: %x\n", &local_i);printf("\n");fun();stafun();printf("\n");fun();int i = 0;printf( "address of local variable i: %x\n", &i);stafun();printf("\n");printf( "address of fun: %x\n", &fun);printf( "address of staticfun: %x\n", &stafun);printf( "address of structHasFun::dynfun: %x\n", &structHasFun::dynFun);printf( "address of structHasFunWithoutMem::dynfun: %x\n", &structHasFunWithoutMem::dynFun);printf( "address of structHasFun::stafun: %x\n", &structHasFun::staFun);printf("\n");printf("si's address of static var si: %x\n", &structHasFun::si);//cout<<"address of structHasFun::dynfun"<<hex<<&structHasFun::dynFun<<endl;printf("size of the struct %d\n",sizeof(structHasFun));printf("size of the struct %d\n",sizeof(structHasFunWithoutMem));printf("\n");printf( "address of stackObj,stackst: %x\n", &stackst);printf( "i's address %x\n", &stackst.i);printf("\n");printf( "address of stackObj,stackst: %x\n", &stackst1);printf( "i's address %x\n", &stackst1.i);printf("\n");printf( "address of heapObj pheapst: %x\n", pheapst);printf( "i's address : %x\n", &(pheapst->i));printf("\n");printf( "address of heapObj pheapst: %x\n", pheapst1);printf( "i's address: %x\n", &(pheapst1->i));printf("\n");return 0;}



0 0
原创粉丝点击