10. 不要在 stack 设置过大的变量以避免堆叠溢位(stack overflow)
由于编译器会自行决定 stack 的上限,某些默认是数 KB 或数十KB,当变量所需的空
间过大时,很容易造成 stack overflow,程式亦随之当掉(segmentation fault)。
可能造成堆叠溢位的原因包括递回太多次(多为程式设计缺陷),
或是在 stack 设置过大的变量。
错误例子:
int array[10000000]; // 在stack宣告过大阵列
std::array<int, 10000000> myarray; //在stack宣告过大std::array
正确例子:
C:
int *array = (int*) malloc( 10000000*sizeof(int) );
C++:
std::vector<int> v;
v.resize(10000000);
说明:建议将使用空间较大的变量用malloc/new配置在 heap 上,由于此时 stack
上只需配置一个 int* 的空间指到在heap的该变量,可避免 stack overflow。
使用 heap 时,虽然整个 process 可用的空间是有限的,但采用动态抓取
的方式,new 无法配置时会丢出 std::bad_alloc 例外,malloc 无法配置
时会回传 null(注2),不会影响到正常使用下的程式功能
备注:
注1. 使用 heap 时,整个 process 可用的空间一样是有限的,若是需要频繁地
malloc / free 或 new / delete 较大的空间,需注意避免造成内存破碎
(memory fragmentation)。
注2. 由于Linux使用overcommit机制管理内存,malloc即使在内存不足时
仍然会回传非NULL的address,同样情形在Windows/Mac OS则会回传NULL
(感谢 LiloHuang 补充)
补充资料:
- https://zh.wikipedia.org/wiki/%E5%A0%86%E7%96%8A%E6%BA%A2%E4%BD%8D
- http://stackoverflow.com/questions/3770457/what-is-memory-fragmentation
- http://library.softwareverify.com/memory-fragmentation-your-worst-nightmare/
overcommit跟malloc:
- http://goo.gl/V9krbB
- http://goo.gl/5tCLQc