溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C++中為什么不要解引用無(wú)效指針

發(fā)布時(shí)間:2021-11-26 13:42:18 來(lái)源:億速云 閱讀:124 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“C++中為什么不要解引用無(wú)效指針”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“C++中為什么不要解引用無(wú)效指針”吧!

ES.65:不要解引用無(wú)效指針

Reason(原因)

解引用例如null等無(wú)效指針,是無(wú)定義的行為,通常會(huì)立即導(dǎo)致程序崩潰,錯(cuò)誤的結(jié)果,或者內(nèi)存破壞。

Note(注意)

本規(guī)則顯而易見(jiàn)而且眾所周知,但卻很難遵守。它會(huì)帶來(lái)好的代碼風(fēng)格,更充分的庫(kù)支持,不需要很大代價(jià)但可以排除違反的靜態(tài)解析。這是關(guān)于C++類型和資源安全模型的論述的重要組成部分。

See also:(參見(jiàn))

  • Use RAII to avoid lifetime problems.

  • 使用RAII避免生命周期問(wèn)題。

  • Use unique_ptr to avoid lifetime problems.

  • 使用unique_ptr避免生命周期問(wèn)題

  • Use shared_ptr to avoid lifetime problems.

  • 使用shared_ptr避免生命周期問(wèn)題

  • Use references when nullptr isn't a possibility.

  • 如果不可能出現(xiàn)空指針,使用引用

  • Use not_null to catch unexpected nullptr early.

  • 使用not_null盡早捕獲意外的空指針。

  • Use the bounds profile to avoid range errors.

  • 使用邊界規(guī)則群組避免范圍錯(cuò)誤。


Example(示例)

void f()
{
   int x = 0;
   int* p = &x;

   if (condition()) {
       int y = 0;
       p = &y;
   } // invalidates p

   *p = 42;            // BAD, p might be invalid if the branch was taken
}

為了解決這個(gè)問(wèn)題,要么擴(kuò)展對(duì)象指針意圖指向的對(duì)象的生命周期,要么縮短指針的生命周期(將解引用操作移到所指向?qū)ο蟮纳芷诮Y(jié)束之前。)

void f1()
{
   int x = 0;
   int* p = &x;

   int y = 0;
   if (condition()) {
       p = &y;
   }

   *p = 42;            // OK, p points to x or y and both are still in scope
}

Unfortunately, most invalid pointer problems are harder to spot and harder to fix.

不幸的是,大多數(shù)無(wú)效指針問(wèn)題難于發(fā)現(xiàn),也難于修改。

Example(示例)

void f(int* p)
{
   int x = *p; // BAD: how do we know that p is valid?
}

這樣的代碼大量存在。在經(jīng)歷了大量測(cè)試之后,大部分情況下可以動(dòng)作,但是如果只看局部很難判斷一個(gè)指針有沒(méi)有可能為空。因此,空指針也是錯(cuò)誤的主要來(lái)源之一。存在很多方法可以處理這個(gè)潛在問(wèn)題:

void f1(int* p) // deal with nullptr
{
   if (!p) {
       // deal with nullptr (allocate, return, throw, make p point to something, whatever
   }
   int x = *p;
}

There are two potential problems with testing for nullptr:

檢查指針是否為空會(huì)有兩個(gè)潛在問(wèn)題:

  • it is not always obvious what to do what to do if we find nullptr

  • 在發(fā)現(xiàn)了空指針時(shí)應(yīng)該做什么并不總是很明確。

  • the test can be redundant and/or relatively expensive

  • 檢查可能是多余的而且/或者代價(jià)相當(dāng)高。

  • it is not obvious if the test is to protect against a violation or part of the required logic.

  • 很難判斷這個(gè)檢查只是為了防止違反還是必要邏輯的一部分。

void f2(int* p) // state that p is not supposed to be nullptr
{
   assert(p);
   int x = *p;
}

這種做法只在斷言檢查有效時(shí)需要付出一定的代價(jià),同時(shí)可以為編譯器/解析器提供有用信息。如果C++得到協(xié)議(contracts)的直接支持的話,效果會(huì)更好:

void f3(int* p) // state that p is not supposed to be nullptr
   [[expects: p]]
{
   int x = *p;
}

Alternatively, we could use gsl::not_null to ensure that p is not the nullptr.

另外,我們可以使用gsl::not_null來(lái)保證p不是空指針。

void f(not_null<int*> p)
{
   int x = *p;
}

These remedies take care of nullptr only. Remember that there are other ways of getting an invalid pointer.

這個(gè)改進(jìn)只處理空指針。別忘了還有其他形式的無(wú)效指針。

Example(示例)

void f(int* p)  // old code, doesn't use owner
{
   delete p;
}

void g()        // old code: uses naked new
{
   auto q = new int{7};
   f(q);
   int x = *q; // BAD: dereferences invalid pointer
}
Example(示例)
void f()
{
   vector<int> v(10);
   int* p = &v[5];
   v.push_back(99); // could reallocate v's elements
   int x = *p; // BAD: dereferences potentially invalid pointer
}
Enforcement(實(shí)施建議)

This rule is part of the lifetime safety profile

本規(guī)則是生命周期規(guī)則群組的一部分

  • Flag a dereference of a pointer that points to an object that has gone out of scope

  • 如果指針指向的對(duì)象已經(jīng)處于生命周期之外,標(biāo)記它的解引用操作。

  • Flag a dereference of a pointer that may have been invalidated by assigning a nullptr

  • 如果指針由于被設(shè)為空指針而無(wú)效時(shí),標(biāo)記它的解引用操作。

  • Flag a dereference of a pointer that may have been invalidated by a delete

  • 如果由于指針指向的對(duì)象被銷毀而無(wú)效時(shí),標(biāo)記它的解引用操作。

  • Flag a dereference to a pointer to a container element that may have been invalidated by dereference

  • 如果指針指向的容器元素由于解引用而無(wú)效時(shí),標(biāo)記它的解引用操作。

到此,相信大家對(duì)“C++中為什么不要解引用無(wú)效指針”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI