您好,登錄后才能下訂單哦!
本篇內容主要講解“C++中為什么不要解引用無效指針”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“C++中為什么不要解引用無效指針”吧!
ES.65:不要解引用無效指針
解引用例如null等無效指針,是無定義的行為,通常會立即導致程序崩潰,錯誤的結果,或者內存破壞。
Note(注意)
本規則顯而易見而且眾所周知,但卻很難遵守。它會帶來好的代碼風格,更充分的庫支持,不需要很大代價但可以排除違反的靜態解析。這是關于C++類型和資源安全模型的論述的重要組成部分。
See also:(參見)
Use RAII to avoid lifetime problems.
使用RAII避免生命周期問題。
Use unique_ptr to avoid lifetime problems.
使用unique_ptr避免生命周期問題
Use shared_ptr to avoid lifetime problems.
使用shared_ptr避免生命周期問題
Use references when nullptr isn't a possibility.
如果不可能出現空指針,使用引用
Use not_null to catch unexpected nullptr early.
使用not_null盡早捕獲意外的空指針。
Use the bounds profile to avoid range errors.
使用邊界規則群組避免范圍錯誤。
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
}
為了解決這個問題,要么擴展對象指針意圖指向的對象的生命周期,要么縮短指針的生命周期(將解引用操作移到所指向對象的生命周期結束之前。)
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.
不幸的是,大多數無效指針問題難于發現,也難于修改。
Example(示例)
void f(int* p)
{
int x = *p; // BAD: how do we know that p is valid?
}
這樣的代碼大量存在。在經歷了大量測試之后,大部分情況下可以動作,但是如果只看局部很難判斷一個指針有沒有可能為空。因此,空指針也是錯誤的主要來源之一。存在很多方法可以處理這個潛在問題:
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:
檢查指針是否為空會有兩個潛在問題:
it is not always obvious what to do what to do if we find nullptr
在發現了空指針時應該做什么并不總是很明確。
the test can be redundant and/or relatively expensive
檢查可能是多余的而且/或者代價相當高。
it is not obvious if the test is to protect against a violation or part of the required logic.
很難判斷這個檢查只是為了防止違反還是必要邏輯的一部分。
void f2(int* p) // state that p is not supposed to be nullptr
{
assert(p);
int x = *p;
}
這種做法只在斷言檢查有效時需要付出一定的代價,同時可以為編譯器/解析器提供有用信息。如果C++得到協議(contracts)的直接支持的話,效果會更好:
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來保證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.
這個改進只處理空指針。別忘了還有其他形式的無效指針。
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
}
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
}
This rule is part of the lifetime safety profile
本規則是生命周期規則群組的一部分
Flag a dereference of a pointer that points to an object that has gone out of scope
如果指針指向的對象已經處于生命周期之外,標記它的解引用操作。
Flag a dereference of a pointer that may have been invalidated by assigning a nullptr
如果指針由于被設為空指針而無效時,標記它的解引用操作。
Flag a dereference of a pointer that may have been invalidated by a delete
如果由于指針指向的對象被銷毀而無效時,標記它的解引用操作。
Flag a dereference to a pointer to a container element that may have been invalidated by dereference
如果指針指向的容器元素由于解引用而無效時,標記它的解引用操作。
到此,相信大家對“C++中為什么不要解引用無效指針”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。