内存管理
程序内存模型
- 静态常量区
- 调用栈
- 堆
静态常量区
-
只读
-
大小固定
-
无法管理
-
可以利用其特性在做离殇做一些特定的优化
-
通过const声明
-const char *teststr = "hello word"; const int a = 10;
调用栈
- 被动分配,被动回收
- 大小再运行期有一个动态调整过程
- 大小有系统限制
- 底大顶小(调用栈整体再内存中开始的内存地址要小于结束的内存地址)
- 为什么变量有作用域
- 为什么不建议使用递归
- 因为栈内存是有大小限制的如果使用递归回使栈内存增大如果栈内存填满会出现StackOverflow的错误(栈溢出)
先进后出,轮流使用
不要再函数内部声明大型模块(大数组,大结构体)
堆
- 堆的大小比较大(甚至可以申请到内存消耗完)
- 主动分配,主动回收
分配方式 | 回收方式 |
---|---|
malloc/calloc | free |
new | delete |
new T[] | delete T[] |
示例:
void * mem = malloc(1024);//c风格 内存分配方式1
void * mem = calloc(1024);//c风格 内存分配方式2
free mem; //c风格 回收内存
int* iptr = new int; //c++ new
delete iptr; //c++ delete
int* iarrptr = new int[1024];//c++ new[]
delete[] iarrptr; //c++ delete[]
- 一直申请不回收会发生什么呢
导致undefined behavior(未定义行为)
- 不要访问未定义的量
指针
- 什么是指针
指针使表示某块数据再内存中的地址,地址为整形,他能表示的范围因平台而不同。
程序类型 | 指针位数 | 等同于 |
---|---|---|
32位程序 | 32 | uint32_t |
64位程序 | 64 | uint64_t |
同一平台上,一般而言,任何一个指针都可以退化为整数表示,所以任何指针本质上都是一个整数,他代表一个内存位置。
//C风格
void* iptr = malloc(1024);//分配一个内存给iptr
int* mem = (int*)iptr;//将iptr转化为int并将地址赋值给mem
*mem = 0;//赋值0给mem
free(mem);
//c++风格
int* ptr = new int;
char* cptr = (char*)ptr;
int c = *(cptr + 1);
delete ptr;
指针的基本操作
- 赋值
- 强转
- 解引用
- 加减
结构体指针
struct MemLayouSample
{
int a;
int b;
int c;
int d;
}
MemLayouSample memSample;
int MemLayouSample::* memoffset = &MemLayouSample::a