[面试题]c++ 内存布局
问c 里面内存的堆栈的布局,有什么区别?
[剖析程序的内存布局](http://blog.csdn.net/drshenlei/article/details/4339110)
[C程序(进程)的内存布局](http://www.cnblogs.com/dejavu/archive/2012/08/13/2627498.html)
BSS,数据段(Data),代码段(Text)。
在C语言中,BSS和数据段保存的都是**静态(全局)变量**的内容。
BSS和数据段的区别:在于BSS保存的是未被初始化的静态变量内容,它们的值不是直接在程序的源代码中设定的。BSS内存区域是匿名的:它不映射到任何文件。如果你写static int cntActiveUsers,则cntActiveUsers的内容就会保存在BSS中。
---------------
ClassA->funcA();
stack 中保存了调用函数过程,所以 需要经过 压栈,出栈。
(C也一样,函数调用过程 也是在stack中)
参考 __cdecl、__stdcall、__fastcall、thiscall 进栈、出栈区别 http://www.cnblogs.com/scotth/p/3163502.html
[C语言中的 static变量、static函数] (http://blog.csdn.net/jeakon/article/details/8488954)
-----------------
PS.
static 关键字修饰的数据成员是静态成员,静态成员被同类的所有对象共享, 可以被类的所有方法访问。
静态方法 只能访问 静态方法 和 静态成员,不能访问任何非静态方法和 非静态成员。
若静态成员变量没有被const 修饰,则其值是可以修改的。(当然const 修饰之后,可以通过**const_cast来修改** )
代码演示:
#include <stdio.h> #include <malloc.h> #define SAFE_DELETE(x) {if ((x)!=NULL) {delete (x); (x)=NULL;}} #define SAFE_DELETEBUFF(x) {if((x)!=NULL) {delete [] (x); (x) = NULL;}} int main() { //====stack的内存分配方式 是从高位 到 低位 , 0x29 ~ 0x11 int a[4] = { 11,22,33,44 }; // a = 0x004cfd40 {11, 22, 33, 44} int a2[4] = { 111,222,333,444 };//a2 = 0x004cfd28 {111, 222, 333, 444} int *addr[4] = { 0 }; //addr = 0x004cfd10 {0x004cfd40 {11}, 0x004cfd44 {22}, 0x004cfd48 {33}, 0x004cfd4c {44}} addr[0] = &a[0]; addr[1] = &a[1]; addr[2] = &a[2]; addr[3] = &a[3]; int *addr2[4] = { 0 };//addr2 = 0x004cfcf8 {0x004cfd28 {111}, 0x004cfd2c {222}, 0x004cfd30 {333}, 0x004cfd34 {444}} addr2[0] = &a2[0]; addr2[1] = &a2[1]; addr2[2] = &a2[2]; addr2[3] = &a2[3]; printf("a 0 = %p, 1= %p,2=%p,3=%p \n", addr[0], addr[1], addr[2], addr[3]); printf("a2 0 = %p, 1= %p,2=%p,3=%p \n", addr2[0], addr2[1], addr2[2], addr2[3]); // 逻辑操作 是无所谓 stack和heap的, int *address = a + 2;//address = 0x004cfd48 {33} int *address0 = a - 2;//address0 = 0x004cfd38 {-858993460} <=== undefine data int *address1 = a + 4;//address1 = 0x004cfd50 {-858993460} <=== undefine data int *address2 = a - 4;//address2 = 0x004cfd30 {333} //====heap 内存分配方式 (内存地址)从低位到高位 0xa1 ~ 0xa9 //new int *b = new int[4];//b = 0x009dcc68 {1} b[0] = 1; b[1] = 2; b[2] = 3; b[3] = 4; // b[4] = '\0'; printf("b 0 = %p, 1= %p,2=%p,3=%p \n", &b[0], &b[1], &b[2], &b[3]); int *c = new int[8*1024];//c = 0x009deaa8 {-842150451} printf("c 0 = %p, 1= %p,2=%p,3=%p \n", &c[0], &c[1], &c[2], &c[3]); int *address10 = b + 2;//address10 = 0x009dcc70 {3} int *address11 = b - 2;//address11 = 0x009dcc60 {65} <=== undefine data int *address12 = b + 100;//address12 = 0x009dcdf8 {0} <=== undefine data int *address13 = b - 100;//address13 = 0x009dcad8 {0} <=== undefine data SAFE_DELETEBUFF(b); SAFE_DELETEBUFF(c); //malloc char *array = (char*) malloc(sizeof(char) * 5); array[0] = 'a'; array[1] = 'b'; array[2] = 'c'; array[3] = 'd'; array[4] = '\0'; free(array); array = NULL; return 0; }
[腾讯面试题 类成员存储问题](http://ask.julyedu.com/question/235)
class A{ virtual void funA(); int mA; //4 byte };
sizeof(A)是多少?
class A{ virtual void funA(); virtual void funB(); int mA; };
sizeof(A)又是多少?
虚函数表存放在哪里?
类中有虚函数,会生成虚函数表,并在该类的实例中添加一个指向虚函数表的指针。
在32位机器上,一个指针占4字节的空间,64位机器上占8字节空间,int的大小由编译器决定,通常占4个字节,
所以在32位机器上第一个sizeof(A)为8,
由于类中无论有多少虚函数,指向虚函数的指针是唯一的,只有一个,所以第二个sizeof(A)也为8。
欢迎指正!
欢迎指正!
虚函数表存放在哪里呢?
@Osiris:虚函数表是由编译器维护的,不同的编译器存放位置可能不一样,可以通过vptr的地址进行查看,经过测试虚函数表在Linux/Unix中存放在可执行文件的只读数据段中(rodata),微软的编译器将虚函数表存放在了目标文件或者可执行文件的常量段中。
分割线=======================================
然后引发一些思考