在學習歸并排序程序中,使用到了遞回函式,而且例程在陣列融合程序中,使用了動態陣列,但是由于編譯器不只支持長度變化的陣列,所以我要將其改寫為指標形式,從而進行自由的長度定義,
原例程:
T aux[r - l + 1];
修改后的程式陳述句:
int size = r - l + 1; T *aux = new int[size];
雖然成功運行,但是一直有些疑問,遞回程序釋放空間的程序是怎樣的呢,能否及時自動釋放記憶體?遞回層數過深是否會發生溢位?
通過查閱相關資料,知道了函式呼叫時通過堆疊(Stack)來實作的,堆疊的特性為先入后出,因此用堆疊來實作遞回呼叫中的存盤分配,每當呼叫一個函式,堆疊就會加一層堆疊幀,函式回傳就減一層堆疊幀,遞回的下層函式沒有回傳,是不會釋放當前資源的,要不然遞回無法繼續執行,但是堆疊的資源是有限,當遞回深度達到一定程度后,就有可能發生溢位,解決方法可以利用回圈函式或者使用堆疊加while回圈來代替遞回函式,不過這不是本文重點,不再具體敘述,
在解決上述動態陣列問題時,也曾考慮使用vector進行替換:
int size = r - l + 1; vector<T> aux; aux.reserve(size);
但是執行時一直報錯vector越界,后來經過語法檢查發現了問題:reserve是容器預留空間,但在空間內并沒有真正創建了元素物件,所以沒有添加新的元素前,是不能有效地訪問這些記憶體空間的,所以訪問的時候就會出現越界現象,導致程式崩潰,
Vec.reserve(r-l+1 ); // 新元素還沒有構造, 僅僅申請記憶體空間 // 此時不能用[]下標訪問元素 for (int i = 0; i < r-l+1; i++ ) { Vec.push_back( i ); //新元素此時才構造 }
終于將坑填好了,將此段程式加入reserve下面就可以正常訪問與修改了,不過此方法有點小缺陷在于當使用了for回圈,導致原排序演算法時間復雜度會變化,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/49349.html
標籤:C++
下一篇:C++ 字串輸入
