SLP(Chapter 6):内存布局和分配(part 1)内存使用方式
1 内存使用方式
1.1 内存管理
不同生存期lifetime对应于三种内存分配机制之一:
- 静态:在整个程序执行过程中保留的绝对地址
- 动态分配
- 栈:以后到先出顺序分配的交易,具有函数调用和返回
- 堆:根据用户的要求,在任意时间分配和处理
1.2 静态分配
Static 静态:是指在编译时和构建程序时链接时发生的情况。(不加载或运行)
由于静态变量由编译时分配,所以编译器可以知道其地址
即局部非static变量位置,编译器不知道,需要通过变量表
- 所有全局变量,无论它们是否已声明为静态变量(对另一个文件里不可见)
- 显式声明为静态的局部变量(仅在声明它们的函数中可见)
- 显式常量(包括字符串常量、集等)
值得注意的是:
- 静态分配的变量:在main运行之前分配和初始化其存储,并且直到main终止才进行释放。
- 静态分配的局部变量:仅在声明它们的函数中可见,但它们不会在每次调用函数时重新初始化。
例子一
例子二
AR: active record
静态分配缺点
- 命名成为一个问题
- 不适合运行时内存分配
例如,根据用户输入分配内存
递归过程是不可能的。
静态分配在程序期间保留内存,但仅临时使用。
1.3 动态分配
动态内存分配是在程序运行时对内存存储的分配。
这与静态内存分配(具有固定持续生命周期)不同。
栈
它是最常见的动态分配形式。
以后到先出顺序分配交易,具有函数调用和返回
是现代编程语言(包括 C 和C++)的标准功能,因为堆栈支持递归。
BTW:对齐不是所有CPU都支持
堆
可以在任意时间分配和释放内存,用于存储任意类型的数据
C语言库
获取内存:
malloc “memory allocation”
void* malloc (size_t size);
参数:希望从堆中获取的字节数
返回:指向刚刚分配的内存的指针
释放内存
void free (void *ptr);
参数:要释放的内存的指针,必须已使用 malloc() 分配
完成后应将指针设置为 NULL
MSDN 微软的库
获取内存:
- 内存分配,元素初始化为 0
void *calloc( size_t num, size_t size ); - 重新分配内存块:realloc
void *realloc( void *ptr, size_t size );
将 ptr 所指向的内存块的大小修改为 size,并将新的内存指针返回。
设之前内存块的大小为 n,如果 size < n,那么截取的内容不会发生变化,如果 size > n,那么新分配的内存不会被初始化。
释放内存 //同
void free( void *memblock );
_msize(void *memblock) 得到获取内存元素大小
内存泄漏:失去对malloc内存的跟踪
栈 VS 堆
- 相同:两者都是从中分配内存的源
- 不同
- 堆栈是自动的(隐式)
当内存处于"范围内"时创建
内存"范围外"时已销毁 - 堆是手动的(显式)
应要求创建
应要求销毁
- 堆栈是自动的(隐式)
请注意,保存堆地址的指针有其自己的作用域。
1.4 内存分配算法
内存分配困难
malloc() 必须分配以前未使用的内存。
所以必须有一个方法来确定哪些内存块可以使用。