這篇文章主要講解了“C++中為什么不要返回指向局部對(duì)象的指針或引用”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C++中為什么不要返回指向局部對(duì)象的指針或引用”吧!
成都創(chuàng)新互聯(lián)是少有的網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、營(yíng)銷型企業(yè)網(wǎng)站、微信平臺(tái)小程序開發(fā)、手機(jī)APP,開發(fā)、制作、設(shè)計(jì)、賣友情鏈接、推廣優(yōu)化一站式服務(wù)網(wǎng)絡(luò)公司,于2013年成立,堅(jiān)持透明化,價(jià)格低,無套路經(jīng)營(yíng)理念。讓網(wǎng)頁驚喜每一位訪客多年來深受用戶好評(píng)
無論直接還是間接,永遠(yuǎn)不要返回指向局部對(duì)象的指針或引用。
Reason(原因)
To avoid the crashes and data corruption that can result from the use of such a dangling pointer.
為了避免使用這個(gè)懸空指針而引起崩潰和數(shù)據(jù)破壞。
Example, bad(反面示例)
After the return from a function its local objects no longer exist:
當(dāng)程序從函數(shù)退出之后,函數(shù)中的局部變量就不再存在了。
int* f()
{
int fx = 9;
return &fx; // BAD
}
void g(int* p) // looks innocent enough
{
int gx;
cout << "*p == " << *p << '\n';
*p = 999;
cout << "gx == " << gx << '\n';
}
void h()
{
int* p = f();
int z = *p; // read from abandoned stack frame (bad)
g(p); // pass pointer to abandoned stack frame to function (bad)
}
Here on one popular implementation I got the output:
這是一段很一般代碼,我得到了以下輸出:
*p == 999gx == 999
I expected that because the call of g()
reuses the stack space abandoned by the call of f()
so *p
refers to the space now occupied by gx
.
我預(yù)期如此是因?yàn)閷?duì)g()的調(diào)用再次使用了調(diào)用f()之后放棄的堆??臻g,因此*p訪問的是現(xiàn)在被gx占用的空間。
Imagine what would happen if fx
and gx
were of different types.
想象一下如果fx和gx是不同類型時(shí)會(huì)發(fā)生什么。
譯者注:變量會(huì)被修改為完全無關(guān)的值。
Imagine what would happen if fx
or gx
was a type with an invariant.
想象一下如果fx和gx是一種包含不變式的類型時(shí)會(huì)發(fā)生什么。
譯者注:不變式會(huì)被莫名其妙地破壞。
Imagine what would happen if more that dangling pointer was passed around among a larger set of functions.
進(jìn)一步想象一下如果懸空指針在更多函數(shù)之間傳遞是會(huì)發(fā)生什么。
譯者注:會(huì)有跟多的函數(shù)和局部變量受到影響。
Imagine what a cracker could do with that dangling pointer.
想象一下破密者會(huì)如果處理懸空指針。
譯者注:破密者可以通過這個(gè)人變量改變函數(shù)的行為。
Fortunately, most (all?) modern compilers catch and warn against this simple case.
幸運(yùn)的是,大部分(所有?)現(xiàn)代編譯器都可以捕捉并對(duì)這個(gè)簡(jiǎn)單的情況報(bào)警。
Note(注意)
This applies to references as well:
這一問題也適用于引用的情況。
int& f(){ int x = 7; // ... return x; // Bad: returns reference to object that is about to be destroyed}
This applies only to non-static
local variables. All static
variables are (as their name indicates) statically allocated, so that pointers to them cannot dangle.
這個(gè)問題只適用于非靜態(tài)全局變量。所有的靜態(tài)變量(就像名稱所表示的)都是靜態(tài)分配內(nèi)存,因此指向它們的指針不會(huì)懸空。Example, bad(反面示例)
Not all examples of leaking a pointer to a local variable are that obvious:
不是所有泄漏指向局部變量指針的示例都是明顯的。
int* glob; // global variables are bad in so many ways
template<class T>
void steal(T x)
{
glob = x(); // BAD
}
void f()
{
int i = 99;
steal([&] { return &i; });
}
int main()
{
f();
cout << *glob << '\n';
}
Here I managed to read the location abandoned by the call of f
. The pointer stored in glob
could be used much later and cause trouble in unpredictable ways.
這段代碼中我設(shè)法讀取函數(shù)f被調(diào)用后放棄的局部變量。保存在glob中的指針可以在很長(zhǎng)時(shí)間之后被使用并以無法預(yù)期的方式帶來麻煩。
Note(注意)
The address of a local variable can be "returned"/leaked by a return statement, by a T&
out-parameter, as a member of a returned object, as an element of a returned array, and more.
局部變量的地址以多種方式被“返回”或者說被泄漏。具體的方式可以是通過返回語句,T&類型的輸出參數(shù),返回值對(duì)象的成員,返回值數(shù)組的元素或者是其它方式。
Note(注意)
Similar examples can be constructed "leaking" a pointer from an inner scope to an outer one; such examples are handled equivalently to leaks of pointers out of a function.
類似地,也可以構(gòu)造出從內(nèi)部作用域向外部作用域“泄漏”指針的例子。這樣的例子等價(jià)于向函數(shù)外部泄漏(指向局部變量的)指針。
A slightly different variant of the problem is placing pointers in a container that outlives the objects pointed to.
這個(gè)問題的稍微不同的版本是將指針放到生命周期超過指針?biāo)赶驅(qū)ο蟮娜萜髦械那闆r。
See also: Another way of getting dangling pointers is pointer invalidation. It can be detected/prevented with similar techniques.
參見:產(chǎn)生懸空指針的另一種情況是指針無效化。它可以通過類似的技術(shù)檢查或防止。
譯者注:指針無效化應(yīng)該是指針本來指向的是一個(gè)有效對(duì)象,但后來對(duì)象被銷毀而指針沒有被同時(shí)清空的情況。
Enforcement(實(shí)施建議)
Compilers tend to catch return of reference to locals and could in many cases catch return of pointers to locals.
編譯器傾向于捕捉返回指向局部變量的引用的情況,也可以在很多情況下捕捉返回指向局部變量的指針的情況。
Static analysis can catch many common patterns of the use of pointers indicating positions (thus eliminating dangling pointers)
靜態(tài)分析可以發(fā)現(xiàn)許多使用指針表示位置的通常形式,這樣就可以排除懸空指針。
感謝各位的閱讀,以上就是“C++中為什么不要返回指向局部對(duì)象的指針或引用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)C++中為什么不要返回指向局部對(duì)象的指針或引用這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
名稱欄目:C++中為什么不要返回指向局部對(duì)象的指針或引用
網(wǎng)頁URL:http://jinyejixie.com/article42/gpiphc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站策劃、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站導(dǎo)航、虛擬主機(jī)、服務(wù)器托管
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)