一個關於臨時物件的BUG(下) (轉)
這一切看起來都非常美妙,但是如果是下面這個例子,會發生什麼情況呢?:namespace prefix = o ns = "urn:schemas--com::office" />
MyClass &mc = foo();
現在將不是將臨時複製到新的物件上面,我僅僅是將它賦值給一個引用,(請注意,這和最開始那個例子有一點區別,在第一個例子裡面,我將一個區域性變數的引用做為了返回值,而在這個例子裡,我是將一個函式返回的臨時變數的引用賦值給一個變數)。那麼,現在將會發生什麼情況呢?臨時物件將在什麼時候被銷燬呢?如果它還是在的執行結束的時候被銷燬,就如同上面那個例子一樣,這段程式碼將因為一個指向不存在的物件的應用而徹底完蛋。但是,請注意,C++標準同意對這種情況提出一種不同尋常的解決辦法:如果一個臨時物件被賦值給一個引用,這個臨時物件在這個引用的生命週期中將不能被銷燬。換句話說,不同於返回一個區域性變數的引用,將一個引用繫結到一個臨時物件上是完全合法的,任何時候使用這個引用,這個物件都應該是有效的。
The
我猜我只能說僅僅當恰當的實現了C++標準,這個引用才可能是有效的。Eugene Gershnik將Listing 2所列的程式碼傳送給了我,它有一個叫foo的函式,返回了一個std::vector
“The instruction at “0x004121b5”referenced memory at “0x00000000”.The memory could not be “read”.”
Listing 2
Assigning a reference to a temporary
// Problem with reference bound to temporary
// The function foo returns a temporary object
// of type std::vector
// to a reference of type const std::vector
// When the expression "int m[80] = {0};" is
// executed,
// the reference bar no longer seems to be valid,
// and the program will crash in the call to
// printf.
// Removing the line "int m[80] = {0};" eliminates
// the problem.
//
// Compile with VC7, with the "Program Database
// for Edit and Continue" debug option.
#include
#include
std::vector
{
std::vector
return ret;
}
int main()
{
const std::vector
int m[80]={0};
std::printf("%d ", bar[0]);
return 0;
}
開始的時候我猜想由於Release版本對“int m[80]= {0};”這一行的造成了這種結果,因為這行程式碼確實什麼也沒有做,我認為這種最佳化消除了在Release下的錯誤。但是當我將程式碼發給Microsoft,並徵求他們的意見的時候,Jeff Peil給我回了信,並指出了真正的原因所在:
這個問題是由於編輯-繼續支援(edit-and-continue debugging support)
的功能而造成的。這個錯誤將在即將釋放的下一版的Visual C++中得到修
正,你可以透過將編輯-繼續除錯支援從編譯選項中去掉而避免這個錯誤
發生(編譯時仍然會產生除錯資訊,你需要做的僅僅是將/ZI選項替換成
/Zi選項)。當然,另外一個解決辦法就是不將引用繫結到臨時物件上去,
這樣你可以繼續使用編輯-繼續除錯支援功能,就像下面的程式碼那樣:
int main()
{
std::vector
std::s(bar,foo());
int m[80]={0};
std::printf(“%d ”, bar[0]);
return 0;
}
—Jeff Peil
雖然上有一點點損失,但Jeff的程式碼工作的很好。這兩個Vector的內容粗看起來是一個代價昂貴的操作,但實際上所有的交換工作就是交換兩個陣列中很少的內部變數,這其中並不涉及到緩衝區的複製,因此交換將在常量時間內完成。
當然如果你想簡單的解決這個問題,可以將表示式“int m[80]= {0};”移動到宣告變數bar之前。因為它們之間不存在什麼倚賴關係,先宣告任何一個都是沒有關係的。
(完)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-956682/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一個關於recyclerView的bugView
- 關於UIInterfaceOrientation的一個bugUI
- Oracle關於nvl的一個BugOracle
- 關於with 臨時表 as的一些用法
- 請教一個關於EJB建立物件時的問題物件
- 關於記憶體的一些bug (轉)記憶體
- mysql關於臨時表的總結MySql
- MySQL關於timestamp和mysqldump的一個“bug”MySql
- 關於contenteditable的IE下的bug
- 關於排序、sort_area_size、臨時表空間(轉)排序
- 發現了一個關於 gin 1.3.0 框架的 bug框架
- C++臨時物件C++物件
- [BUG反饋]兩個關於釋出文章的BUG
- 關於Oracle中重啟資料庫的一個bugOracle資料庫
- 關於'kksfbc child completion' wait的一個bugAI
- 踩到一個關於分散式鎖的非比尋常的BUG!分散式
- 關於Oracle臨時表的使用的小經歷Oracle
- [轉]轉一個關於優化sql的文章優化SQL
- 關於Oracle臨時表的使用的小經歷和一點疑問?Oracle
- 關於 oracle 臨時表 ORA-14452Oracle
- oracle串物件相關的bugOracle物件
- dataguard新增臨時資料檔案的bug
- onethink安裝時的一個bug
- 斑竹,能否講一下,關於值物件,應用。物件
- Sqlserver 關於臨時表和表變數的總結SQLServer變數
- 舒服了,踩到一個關於分散式鎖的非比尋常的BUG!分散式
- win下使用expdp的enclude引數時一個物件和多個物件的幾種寫法!物件
- 關於ASMLib的一個小事,記錄一下ASM
- 關於線上的bug什麼時候修復的思考
- 初學 GoLang 遇到的一個關於時間的坑...Golang
- transitionEnd和animationEnd的一個臨時解決方案
- oracle臨時表的用法(轉)Oracle
- 關於CENTOS 執行時間異常到幾百萬的BUGCentOS
- 關於全域性臨時表DML特性案例體現
- 一個關於Java Socket的問題,大家看一下Java
- 【基礎知識】基於事物的臨時表和基於會話的臨時表會話
- 用go封裝一下臨時tokenGo封裝
- std::ostringstream::str()返回臨時物件物件