"AddressSanitizer: stack-use-after-scope"尝试访问指针向量的元素时



为什么下面的代码是

#include <iostream>
#include <vector>
typedef struct Number {
int number = 15;
} Number;
int main() {
std::vector<Number*> nums(5);
for (size_t i = 0; i < nums.size(); ++i) {
Number num;
nums[i] = &num;
}
std::cout << nums[1]->number << "n";
return 0;
}

触发器";AddressSanitizer:作用域之后的堆栈使用";,但当我评论第15:std::cout << nums[5]->number << "n";行时,它编译得很好?如何修复?

编译命令:clang++ main.cpp -fsanitize=address,undefined -fno-sanitize-recover=all -std=c++17 -O2 -Wall -Werror -Wsign-compare -g -o debug_solution && ./debug_solution

问题是,您存储的指针指向堆栈上超出范围并被销毁的值,留下一个悬空指针。

std::vector<Number*> nums(5);
for (size_t i = 0; i < nums.size(); ++i) {
Number num;
nums[i] = &num;
// num goes out of scope here and num[i] has a dangling pointer
//    to an invalid object
}
std::cout << nums[1]->number << "n";

在这个玩具示例中,我认为根本没有理由使用指针,而修复方法只是使用std::vector<Number>:

std::vector<Number> nums(5);
// per comment by @user4581301
// this loop is not really needed, as the constuctor will
// default-construct the elements for you
for (size_t i = 0; i < nums.size(); ++i) {
Number num;
nums[i] = num;
}
std::cout << nums[1].number << "n";

如果确实需要在堆上进行动态内存分配,则应考虑使用std::vector<std::unique_ptr<Number>>std::vector<std::shared_ptr<Number>>,具体取决于对象是否需要在多个组件之间共享。

最新更新