理解自:http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/
内存分配
一个程序在用的内存分为几个片段:
- code segment 存放代码的地方,这部分是只读的
- bss segment 存放全局默认静态变量的地方
- data segment 全局变量和静态变量
- 堆 动态分配内存的片段
- call stack 放置函数中的local参数,还有其他函数相关的东西(函数内作用域,出去就被移除)
我们平时说的代码内存分配的堆栈,指的应该就是上面所说的heap以及call stack。
heap
使用new来在堆中分配内存:
int *ptr = new int; // ptr is assigned 4 bytes in the heap
int *array = new int[10]; // array is assigned 40 bytes in the heap
当delete掉一个指针之后,内存上对应的内容并没有被马上移除,而只是被标注为可使用的状态而已。
使用动态分配内存的优势劣势
- 在堆上动态分配内存可以说是比较慢的
- 在被delete之前这块内存将一直被占用
- 使用一个指针才能够引用到这块内存,而一个指针间接引用会比直接引用一个参数要慢
- 堆很大,所以大数组,struct,类都能被分配在这儿
stack
所有被调起且未结束的函数的数据,都在栈里。
执行一个新函数的时候这个函数本身以及参数都会入栈,当函数执行结束的时候它的所有信息都已全部出栈。
栈溢出
由于栈不是一块很大的内存(Windows里面只给了1MB),所以很容易爆满。有几种情况会导致栈溢出:
- 申请一块超大的内存(比如大数组)
int main()
{
int stack[100000000];
return 0;
}
- 太多的函数调用,比如无限次调用自身
函数栈的优势劣势
- 分配内存贼快
- 有作用时间,当函数终结了,意味着作用时间结束,引用这块内存将变得非法
- 内存可以直接被变量引用
- 大内存的东西就不要放这儿了