十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
本篇内容主要讲解“C++中为什么不要解引用无效指针”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++中为什么不要解引用无效指针”吧!
成都创新互联公司主营红山网站建设的网络公司,主营网站建设方案,成都app软件开发,红山h5微信小程序开发搭建,红山网站营销推广欢迎红山等地区企业咨询
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 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 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++中为什么不要解引用无效指针”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!