十三誡增修--10:不要在 stack 設置過大的變數以避免堆疊溢位
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
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 223.136.189.53
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1464012158.A.3DA.html
推
05/23 22:20, , 1F
05/23 22:20, 1F
→
05/23 22:21, , 2F
05/23 22:21, 2F
推
05/23 22:22, , 3F
05/23 22:22, 3F
→
05/23 22:22, , 4F
05/23 22:22, 4F
→
05/23 22:23, , 5F
05/23 22:23, 5F
→
05/23 22:25, , 6F
05/23 22:25, 6F
→
05/23 22:25, , 7F
05/23 22:25, 7F
→
05/23 22:25, , 8F
05/23 22:25, 8F
→
05/23 22:26, , 9F
05/23 22:26, 9F
→
05/23 22:28, , 10F
05/23 22:28, 10F
→
05/23 22:29, , 11F
05/23 22:29, 11F
推
05/23 22:32, , 12F
05/23 22:32, 12F
→
05/23 22:38, , 13F
05/23 22:38, 13F
→
05/23 22:40, , 14F
05/23 22:40, 14F
→
05/23 22:40, , 15F
05/23 22:40, 15F
→
05/23 22:41, , 16F
05/23 22:41, 16F
→
05/23 22:41, , 17F
05/23 22:41, 17F
→
05/23 22:42, , 18F
05/23 22:42, 18F
※ 編輯: wtchen (223.136.189.53), 05/23/2016 23:02:14
→
05/25 12:02, , 19F
05/25 12:02, 19F
抱歉造成誤解....
※ 編輯: wtchen (220.128.143.228), 05/25/2016 12:53:42
推
05/27 17:32, , 20F
05/27 17:32, 20F
→
05/27 17:32, , 21F
05/27 17:32, 21F
推
05/27 18:52, , 22F
05/27 18:52, 22F
→
05/27 18:58, , 23F
05/27 18:58, 23F
→
05/27 18:58, , 24F
05/27 18:58, 24F
→
05/27 18:59, , 25F
05/27 18:59, 25F
→
05/27 18:59, , 26F
05/27 18:59, 26F
→
05/27 18:59, , 27F
05/27 18:59, 27F
→
05/27 18:59, , 28F
05/27 18:59, 28F
→
05/27 18:59, , 29F
05/27 18:59, 29F
→
05/27 18:59, , 30F
05/27 18:59, 30F
→
05/27 19:00, , 31F
05/27 19:00, 31F
→
05/27 19:00, , 32F
05/27 19:00, 32F
→
05/27 19:00, , 33F
05/27 19:00, 33F
→
05/27 19:00, , 34F
05/27 19:00, 34F
→
05/27 19:00, , 35F
05/27 19:00, 35F
→
05/27 19:00, , 36F
05/27 19:00, 36F
→
05/27 19:00, , 37F
05/27 19:00, 37F
→
05/27 19:01, , 38F
05/27 19:01, 38F
→
05/27 19:01, , 39F
05/27 19:01, 39F
→
05/27 19:01, , 40F
05/27 19:01, 40F
→
05/27 19:01, , 41F
05/27 19:01, 41F
→
05/27 19:01, , 42F
05/27 19:01, 42F
→
05/27 19:02, , 43F
05/27 19:02, 43F
→
05/27 19:04, , 44F
05/27 19:04, 44F
→
05/27 19:07, , 45F
05/27 19:07, 45F
→
05/27 19:08, , 46F
05/27 19:08, 46F
→
05/27 19:09, , 47F
05/27 19:09, 47F
→
05/27 19:16, , 48F
05/27 19:16, 48F
→
05/27 19:16, , 49F
05/27 19:16, 49F
推
05/27 19:18, , 50F
05/27 19:18, 50F
→
05/27 19:20, , 51F
05/27 19:20, 51F
→
05/27 19:20, , 52F
05/27 19:20, 52F
→
05/27 20:32, , 53F
05/27 20:32, 53F