不可解引用已失效的指针
14.4 ID_danglingDeref
对象的生命周期结束后,指向该对象的指针即失效,解引用已失效的指针会导致标准未定义的行为。
示例:
int foo() {
int* p = (int*)malloc(8 * sizeof(int));
if (cond) {
....
free(p);
}
return p[0]; // Non-compliant, ‘p’ may be deallocated
}
例中指针 p 指向一个数组,数组被释放后生命周期结束,p 的值不变但已无效,这种情况被形象地称为“指针悬挂”,被悬挂的指针和未初始化的指针统称“野指针”,均不可被解引用。
又如:
int foo(int i) {
int* p = &i;
if (cond) {
int j = 0;
....
p = &j; // Bad practice
}
return *p; // Non-compliant, ‘p’ may be a dangling pointer
}
例中局部变量 j 的地址被传给了外层作域中的指针 p,j 的生命周期结束后,p 的值会失效。应避免内层作用域中的地址向外层传递,可参见 ID_localAddressFlowOut 的进一步讨论。
另外,在 C++ 代码中,还应避免持有可被自动销毁的对象的地址,如:
int bar(vector<int>& v) {
int* p = &v.front(); // Bad practice
v.push_back(1);
return *p; // ‘p’ may be invalid
}
例中指针 p 持有 vector 容器中对象的地址,随着容器容量的增加原对象的地址可能不再有效。
又如:
int baz() {
auto u = make_unique<int>();
auto p = u.get(); // Bad practice
u = make_unique<int>();
return *p; // ‘p’ is invalid
}
例中指针 p 持有智能指针指向对象的地址,当智能指针指向新对象时,原对象的地址不再有效。
相关
依据
ISO/IEC 9899:1999 6.5.3.2(4)-undefined
ISO/IEC 9899:2011 6.5.3.2(4)-undefined