C/C++的内存分区
1. 堆区
堆区存放的是动态申请的内存,以new,或则malloc申请的内存。
2. 栈区
栈区顾名思义是一个栈,它将程序的变量压入,退出作用域时弹出。
3. 静态/全局区
存储全局变量和函数的区域,一旦程序启动,就不再增减。
4. 常量区
存放常量的区域。
5 代码区
存放函数执行代码的区域
上代码
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
using namespace std;
static int a=0;
const int b=1;
int c=2;
static const int d=3;
#define byte unsigned char
void function(){
cout<<endl;
}
static void function1(){
cout<<endl;
}
class CA{
public:
CA(){
}
void functionCA(){
}
static void functionst(){
}
virtual void functionv(){
cout<<endl;
}
};
int main()
{
CA ca;
CA * ca1=new CA;
static int e=10;
const int f=11;
int g=12;
static const int h=13;
const static int h1=13;
const byte *pa=(byte*)malloc(96*sizeof(byte));
union {
void *pv;
void(CA::*pfn)();
} u;
u.pfn = &CA::functionCA;
byte *pb=new byte[96];
cout<<"malloc指针:"<<(int*)pa<<endl;
cout<<"new指针:"<<(int*)pb<<endl;
cout<<"对象地址:"<<&ca<<endl;
cout<<"new对象地址:"<<ca1<<endl;
cout<<"对象函数地址:"<<hex<<(int*)(long)u.pv<<endl;
cout<<"对象静态函数地址:"<<hex<<(int*)(long)&(CA::functionst)<<endl;
//u.pfn = &CA::functionv;
cout<<"对象虚函数函数地址:"<<((int*)*((int*)&ca+0))<<endl;
cout<<"对象虚函数函数地址:"<<((int*)*((int*)&ca+1))<<endl;
//cout<<(int*)&123<<endl;
cout<<"静态全局变量:"<<&a<<endl;
cout<<"全局常量:"<<&b<<endl;
cout<<"全局变量:"<<&c<<endl;
cout<<"静态全局常量:"<<&d<<endl;
cout<<"静态局部变量:"<<&e<<endl;
cout<<"局部常量:"<<&f<<endl;
cout<<"局部变量:"<<&g<<endl;
cout<<"静态局部常量:"<<&h<<endl;
cout<<"局部静态常量:"<<&h1<<endl;
cout<<"全局函数地址:"<<hex<<(int*)&function<<endl;
cout<<"全局静态函数地址:"<<hex<<(int*)&function<<endl;
string str="12345asd";
cout<<"字符串地址:"<<&str<<endl;
cout<<"字符串常量地址:"<<&"12345asd"<<endl;
delete[]pa,pb;
pa=0,pb=0;
delete ca1;
ca1=0;
return 0;
}
结果
malloc指针:0x91bc40
new指针:0x91bcb0
对象地址:0x7fff056aede0
new对象地址:0x91bc20
对象函数地址:0x402418
对象静态函数地址:0x402423
对象虚函数函数地址:0x402800
对象虚函数函数地址:0
静态全局变量:0x6042f0
全局常量:0x402650
全局变量:0x604118
静态全局常量:0x402654
静态局部变量:0x60411c
局部常量:0x7fff056aedd8
局部变量:0x7fff056aeddc
静态局部常量:0x4027e8
局部静态常量:0x4027ec
全局函数地址:0x401d34
全局静态函数地址:0x401d34
字符串地址:0x7fff056aee10
字符串常量地址:0x4027b5
凡是在编译时不能确定大小的区域,都在堆区,如动态分配的内存块等。
凡是全局的变量和局部的静态变量,即虽然在编译的时候可以确定大小,但是在程序运行时还保留有修改权限的量,都在静态/全局区。
凡是全局的,一旦编译完毕就不改变(大小和内容)的,(即在整个程序的生存周期都存在的),都在常量区。 比如全局常量,全局函数,静态类函数,全局静态函数等,已经实例化的虚函数也在常数区。
凡作用区域不是整个函数周期的非静态量都在栈区。 局部变量和局部非静态常量都在栈区,局部的静态常量在常数区,非new的类对象等。
- 从上面的地址数据来看,常数区和函数区在一个地址,可以说函数区存放了常量,或则常量区存放了函数
额外知识点
- 取得类成员函数的地址
union {
void *pv;
void(CA::*pfn)();
} u;
u.pfn = &CA::functionCA;
cout<<u.pv<<endl;
- 取得虚函数的地址,利用虚函数表的函数序号,函数序号对应的地址就是虚函数的地址,虚函数表在对象的开头
CA ca;
cout<<"对象虚函数函数地址:"<<((int*)*(int*)(&ca))<<endl;