使用过期的堆栈地址¶
ID: cpp/using-expired-stack-address
Kind: path-problem
Security severity: 9.3
Severity: error
Precision: high
Tags:
- reliability
- security
- external/cwe/cwe-825
Query suites:
- cpp-code-scanning.qls
- cpp-security-extended.qls
- cpp-security-and-quality.qls
此规则查找可能指向已过期堆栈帧中局部变量的指针使用。指向局部变量的指针仅在函数返回之前有效,之后它将变为悬空指针。
建议¶
如果需要获取局部变量的地址,请确保该地址仅存储在不会比局部变量存活时间更长的内存中。例如,可以安全地将地址存储在另一个局部变量中。类似地,只要另一个函数仅在本地使用局部变量的地址并且不将其存储在非局部内存中,就可以安全地将该地址传递给另一个函数。
如果需要存储一个将在当前函数作用域之外存活的地址,则应在堆上分配该地址。应注意确保在不再需要内存时将其释放,尤其是在使用低级内存管理例程(例如
malloc
/free
或new
/delete
)时。现代 C++ 应用程序通常使用智能指针(例如std::shared_ptr
)来减少内存泄漏的可能性。
示例¶
static const int* xptr;
void localAddressEscapes() {
int x = 0;
xptr = &x;
}
void example1() {
localAddressEscapes();
const int* x = xptr; // BAD: This pointer points to expired stack allocated memory.
}
void localAddressDoesNotEscape() {
int x = 0;
xptr = &x;
// ...
// use `xptr`
// ...
xptr = nullptr;
}
void example2() {
localAddressDoesNotEscape();
const int* x = xptr; // GOOD: This pointer does not point to expired memory.
}