- struct student
- {
- char* name;
- int age;
- int collage;
- };
-
- static void WriteAndChangeStudent(struct student data)
- {
- fprintf(stdout,data.name);
- data.age = 109;
- printf("%d",data.age);
- }
-
- int main(int argc, char **argv)
- {
- struct student* one = new student();
- memset(one,0,sizeof(one));
- one->age = 490;
- one->name = "campolake";
- one->collage = 4;
- WriteAndChangeStudent(*one);
- return 0;
- }
为了弄清楚各个语言的内存布局的具体情况,用一些简单的例子来测试一下。
第一、先看结构struct的内存结构
struct student* one = new student();
- void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)//调用了new运算符
- { // try to allocate size bytes
- void *p;
- while ((p = malloc(size)) == 0) //在堆上申请内存,如果申请成功则返回。
- if (_callnewh(size) == 0)
- { // report no memory
- static const std::bad_alloc nomem;
- _RAISE(nomem);
- }
-
- return (p);
- }
简单struct的结构
- one->age = 490;
- 000A148F mov eax,dword ptr [one] 将one的地址放入eax寄存器
- 000A1492 mov dword ptr [eax+4],1EAh //第一个四字节是char指针。age 在第二个四字节上
- one->name = "campolake";
- 000A1499 mov eax,dword ptr [one]
- 000A149C mov dword ptr [eax],offset string "campolake" (0A574Ch) //将字符串驻留池中的地址赋值
- one->collage = 4;
- 000A14A2 mov eax,dword ptr [one]
- 000A14A5 mov dword ptr [eax+8],4 //collage 在第三个dword
从这里看出结构式按照各个类型的大小和声明顺序来在内存中布局,给其赋值的时候按照各个变量的偏移量来操作。指针保存了其地址。
在结构中增加函数指针,看内存的变化。
修改结构,增加函数指针
- struct student
- {
- char* name;
- int age;
- int collage;
- void (*showme)(student* stu);
- };
给函数指针赋值,并调用。
- one->showme = showmyself;
- (*one->showme)(one);
对应的汇编
- one->showme = showmyself;
- 0139151C mov eax,dword ptr [one]
- 0139151F mov dword ptr [eax+0Ch],offset showmyself (1391154h)
我们看到函数指针占据结构末尾的4个字节。指向方法区的地址。那么方法区又是如何分布的呢?
面向对象的成员方法又是如何实现,如何布局的呢?
|