分享

从汇编来看C++中struct和class的内存布局

 astrotycoon 2015-10-14
一段简单的c++代码代码  收藏代码
  1. struct student  
  2. {     
  3.     char* name;  
  4.     int age;  
  5.     int  collage;  
  6. };  
  7.   
  8. static void WriteAndChangeStudent(struct student data)  
  9. {  
  10.     fprintf(stdout,data.name);  
  11.     data.age = 109;  
  12.     printf("%d",data.age);  
  13. }  
  14.   
  15. int main(int argc, char **argv)  
  16. {   
  17.     struct student* one = new student();      
  18.     memset(one,0,sizeof(one));  
  19.     one->age = 490;  
  20.     one->name = "campolake";  
  21.     one->collage = 4;  
  22.     WriteAndChangeStudent(*one);  
  23.     return 0;  
  24. }  

 

为了弄清楚各个语言的内存布局的具体情况,用一些简单的例子来测试一下。

 

第一、先看结构struct的内存结构

struct student* one = new student();

 

C代码  收藏代码
  1. void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)//调用了new运算符  
  2.         {       // try to allocate size bytes  
  3.         void *p;  
  4.         while ((p = malloc(size)) == 0) //在堆上申请内存,如果申请成功则返回。  
  5.                 if (_callnewh(size) == 0)  
  6.                 {       // report no memory  
  7.                 static const std::bad_alloc nomem;  
  8.                 _RAISE(nomem);  
  9.                 }  
  10.   
  11.         return (p);  
  12.         }  

 简单struct的结构

 

C代码  收藏代码
  1.     one->age = 490;  
  2. 000A148F  mov         eax,dword ptr [one]  将one的地址放入eax寄存器  
  3. 000A1492  mov         dword ptr [eax+4],1EAh  //第一个四字节是char指针。age 在第二个四字节上  
  4.     one->name = "campolake";  
  5. 000A1499  mov         eax,dword ptr [one]    
  6. 000A149C  mov         dword ptr [eax],offset string "campolake" (0A574Ch)  //将字符串驻留池中的地址赋值  
  7.     one->collage = 4;  
  8. 000A14A2  mov         eax,dword ptr [one]    
  9. 000A14A5  mov         dword ptr [eax+8],4  //collage 在第三个dword   
 

从这里看出结构式按照各个类型的大小和声明顺序来在内存中布局,给其赋值的时候按照各个变量的偏移量来操作。指针保存了其地址。

在结构中增加函数指针,看内存的变化。

 

修改结构,增加函数指针

C代码  收藏代码
  1. struct student  
  2. {     
  3.     char* name;  
  4.     int age;  
  5.     int  collage;  
  6.     void (*showme)(student* stu);  
  7. };  

 给函数指针赋值,并调用。

Cpp代码  收藏代码
  1. one->showme = showmyself;  
  2. (*one->showme)(one);  

 对应的汇编

C代码  收藏代码
  1.     one->showme = showmyself;  
  2. 0139151C  mov         eax,dword ptr [one]    
  3. 0139151F  mov         dword ptr [eax+0Ch],offset showmyself (1391154h)   

 我们看到函数指针占据结构末尾的4个字节。指向方法区的地址。那么方法区又是如何分布的呢?

面向对象的成员方法又是如何实现,如何布局的呢?

 

 

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多