2010-04-23 76 views
0

代碼段(正常指針)普通指針VS自動指針(標準:: auto_ptr的)

int *pi = new int; 
int i = 90; 
pi = &i; 
int k = *pi + 10; 
cout<<k<<endl; 
delete pi; 

[Output: 100] 

代碼段(自動指針)

案例1:

std::auto_ptr<int> pi(new int); 
int i = 90; 
pi = &i; 
int k = *pi + 10; //Throws unhandled exception error at this point while debugging. 
cout<<k<<endl; 
//delete pi; (It deletes by itself when goes out of scope. So explicit 'delete' call not required) 

案例2:

std::auto_ptr<int> pi(new int); 
int i = 90; 
*pi = 90; 
int k = *pi + 10; 
cout<<k<<endl; 

[Output: 100] 

有人可以告訴爲什麼它沒有爲案例1工作?

+0

情況1實際上應該編譯失敗(沒有操作符來執行'pi =&i;'),所以我看不到你如何調試這段代碼。 – visitor 2010-04-23 11:05:36

+0

它沒有編譯失敗。 (我正在編譯與vc8) – AKN 2010-04-23 12:16:20

+0

你似乎碰到過這個bug:http://connect.microsoft.com/VisualStudio/feedback/details/98871/ - 好吧,@visitor已經找到了一個。 – 2010-04-23 13:01:53

回答

2

您試圖將auto_ptr綁定到堆棧分配的變量。

std::auto_ptr<int> pi(new int); 
int i = 90; 
pi = &i; 

從來沒有嘗試這樣做, - 只能綁定auto_ptrnew分配的變量。否則auto_ptr會嘗試delete一個堆棧分配變量,這是未定義的行爲。

+0

好的。我改變如下,它的工作。 { int * i = new int; * i = 90; pi =&i; } 有趣的一點。當我將'i'複製到'pi'時,'i'變成了NULL。 (我認爲這是如何設計auto_ptr工作) – AKN 2010-04-23 07:15:02

2

情況1 無法編譯,因爲您根本無法將普通指針指定爲auto_ptr。如果你想改變的是auto_ptr照顧的指針,你可以使用復位方法:

pi.reset(&i); 

現在pi將其刪除早前存儲指針。

但是,在這裏您將存儲堆棧分配變量的地址,其中不得刪除std::auto_ptr的目的是管理一個動態分配的變量。


你所用VC++ 2005觀察似乎是一個功能(的指針分配給std::auto_ptr能力),這是在標準顯然是不特定的實現中的錯誤(無論該不該編譯) 。

在下一個標準std::auto_ptr將被棄用,所以你可能更傾向於實驗更聰明的指針(boost::scoped_ptrboost::shared_ptr)。

+0

感謝您的看法。 當我在調試過程中像pi =&i一樣分配時,在解引用(*)時,它引發了一個異常。當我像pi.reset(&i)那樣分配時,它在解引用時成功了,但是當程序超出範圍時,它就崩潰了。我可以理解這一點,因爲auto_ptr試圖在方法超出範圍時刪除堆棧分配的內存。 – AKN 2010-04-23 12:22:23

+0

看來你已經偶然發現了庫實現中的一個錯誤:http://connect.microsoft.com/VisualStudio/feedback/details/98871/memory-corruption-in-auto-ptr-operator-auto-ptr-ref。請記住,分配一個指向'auto_ptr'的指針是不可移植的(我認爲這是標準的意圖,這不應該編譯,但可能沒有指定)。 – visitor 2010-04-23 12:42:12