續上集…
-
STL container 的 clear 真的就 clear 乾淨了嗎?
相信很多人在寫 C++ 時,都會想利用 STL 來省去一些造輪子的麻煩,其中最常被使用的就是像
std::vector或std::list這類的 container,常常有人就拿它們來當 variable-length 的 array 來解決問題。然後可能就會有像這樣子的 code 出現:
... std::vector<myclass *> vec; ... MyClass* pObj = new MyClass(...); vec.push_back(pObj); ... ... // 用完 vec 之後,試圖把它清除掉 vec.clear();
很多人以為這樣寫,
clear()method 就會幫你把曾經放進去的 element 給清乾淨了,可惜並不是這麼美好!沒錯,clear()的確是會把vec裡的 elements 都清掉沒錯,但你有沒有注意到,vec的 element type 是MyClass*,是個指標的資料型態,也就是說:呼叫clear()method 清掉了這些個指標,但卻沒有清掉指標所指到的 object!所以最起碼你應該這麼寫:// 以 iterator 走訪整個 vec 裡的元素, // 然後一一 delete 掉指到的 object for (std::vector<myclass *>::iterator iter = vec.begin(); iter != vec.end(); ++iter) { delete *iter; } vec.clear();
如果你有大量使用 STL 習慣的人,一定要小心 container 裡的 element 是不是真的都清乾淨了。
-
如果你很懶,請愛用
std::auto_ptr之前有提到 new 過就不要忘記 delete 它,但如果你常常忘記 delete 的話,不妨用
std::auto_ptr來幫你吧!std::auto_ptr是一個 smart pointer ,它雖然是一個 templated class,但它的 object 用起來就好像一般的指標一樣,差別在於:當這個 object 被 destroy 時,它會檢查指到的記憶體是不是經由 new 所配置來的,如果是,就順便清掉!下面就用簡單的例子來說明:#include <memory> // 要引入 memory 標頭檔 ... { std::auto_ptr<myclass> pObj(new MyClass()); ... // 這時就可以使用 pObj->xxx() 來呼叫 method, // 就好像你用 MyClass *pObj; 宣告一樣。 ... // 此時 pObj 被 destroy 了, //而它指到的記憶體也會被釋放。 } ...
看起來方便多了,是吧?不過沒用過
std::auto_ptr的人要注意到,它是沒辦法經由 copy assignment 來與另一個std::auto_ptrobject 來 share 指到的記憶體位置。比方說下列的 code 就會使p1最後指到null:... std::auto_ptr<myclass> p1(new MyClass()); std::auto_ptr<myclass> p2; p2 = p1; ...
這樣
p2會指到原本p1指到的記憶體,但卻讓p1指到 null 了。如果你想要使用可以 share 的 smart pointer,或許你可以參考 boost library 裡的 shared_pointer,或是等待 C++ 2.0 的標準函式庫(詳情可見 TR1 draft)
簡單地寫了最近常碰到的問題,歡迎各方高手不吝賜教。:)
文章分類:
標籤:


2008/01/10 2:55 pm
不好意思,我記得autoptr會無差別delete他所存的指標耶@@
#include
#include
class Dummy
{
public:
Dummy()
{
std::cout << “A dummy created” << std::endl;
}
~Dummy()
{
std::cout << “Dummy deleted” << std::endl;
}
};
void dummyFun(Dummy* ptrDummy)
{
std::cout << “Function started” << std::endl;
std::auto_ptr aPtr(ptrDummy);
std::cout << “Funtion ended” << std::endl;
}
int main()
{
std::cout << “Program started” << std::endl;
Dummy iAmDummy;
dummyFun(&iAmDummy);
std::cout << “Program ended” << std::endl;
return 0;
}
在VC2008 express中如果在debug build中在auto_ptr嘗試delete從main傳過去的資料VC2008會自動break報告問題出現,而在release build中在dummyFun會被delete一次而離開main再destruct一次。
是因為這是VC2008用的政策嗎?
2008/01/10 2:59 pm
這…VC對 STL 的實作我一直都覺得很神妙,也許我沒辦法回答您 :(
2008/01/10 2:59 pm
抱歉,我不應該在這邊貼code的orz
http://rafb.net/p/vnAGy329.html