答同學關於C/C++問題

最近實驗室有同學正在自修關於C/C++方面的問題,在練習寫函式的時後碰到些小問題,於是在MSN傳訊問我。他正在練習寫一個把c語言字串作反轉的函式,結果執行的時後當掉,他傳給我的函式原始程式碼如下:

char *rev(const char *p)
{
char *q;
int size = sizeof(p);

while((size--)>0)
*(q++) = *(p+size);

return q;
}

這個函式寫法在邏輯上是沒有錯,不過出問題的地方在於將函式中Local變數的位址回傳。當函式返回時,所有Local變數都會被清除,於是造成錯誤。

一個最簡單的方式是,把要回傳的反轉字串宣告成Global變數,這樣在函式返回時,就不會造成因清除而產生的錯誤。但是這種寫法有個很大的缺點,就是程式不具有re-entrant的特性。因為如果使用者程式是multi-thread且都有可能呼叫這個函式的話,那麼由於multi-thread共用相同的全域空間,這將有可能造成問題。

另一個方法是使用動態記憶體配置,這樣函式就具備了re-entrant的特性,也不會在函式返回時產生錯誤。但是使用動態配置在c/c++中是必須要程式自己作釋放記憶體動作的,這會讓函式在使用上很不直覺,而且感覺也不對稱。記憶體配置在函式內,而記憶體釋放在函式外,並且還很可能會不小心忘了把記憶體釋放!

比較折衷也較直覺的方式是參考類似C語言函式庫的設計方式,傳入兩個字元陣列變數,第一個是來源字串,第二個用來作為儲存反轉字串之用,這樣對程式使用者來說應該是比較便利與直覺的一種方式。

Comments:

blog comments powered by Disqus

Blogger Templates by Blog Forum