☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

不可解引用已失效的指针

14.4 ID_danglingDeref
目录 › next › previous

对象的生命周期结束后,指向该对象的指针即失效,解引用已失效的指针会导致标准未定义的行为。

示例:

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 持有智能指针指向对象的地址,当智能指针指向新对象时,原对象的地址不再有效。

相关

ID_illAccess ID_illLifetime ID_localAddressFlowOut ID_missingResetNull

依据

ISO/IEC 9899:1999 6.5.3.2(4)-undefined ISO/IEC 9899:2011 6.5.3.2(4)-undefined

参考

CWE-416 CWE-825 C++ Core Guidelines ES.65 SEI CERT EXP54-CPP
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.