C++访问指针vector触发AddressSanitizer stack-use-after-scope报错原因与修复
错误触发原因
你遇到的stack-use-after-scope错误本质是访问了作用域已经失效的栈内存,具体原因如下:
- 循环体内定义的
Number num是栈上的局部变量,每次for循环迭代结束后,当前迭代的num的生命周期就会终止,对应的栈内存会被系统回收。 - 你在循环中将
&num(局部变量的栈地址)存入了vector,循环结束后vector里保存的所有指针全部都是野指针。 - 后续执行
std::cout << nums[1]->number << "\n"时,相当于访问已经被回收的栈内存,直接触发AddressSanitizer的栈作用域后使用检测。 - 你注释掉cout行后代码没有触发报错,是因为此时没有任何访问野指针的操作,程序不会触发内存错误检测。
修复方案
根据你的使用场景,可以选择以下任意一种方案修复:
方案1:vector直接存储对象(最推荐,无额外内存管理成本)
修改vector的类型为存储Number对象而非指针,避免手动管理内存:
#include <iostream> #include <vector> typedef struct Number { int number = 15; } Number; int main() { std::vector<Number> nums(5); // 不需要额外赋值,默认构造已经完成初始化 std::cout << nums[1].number << "\n"; return 0; }
方案2:使用堆内存存储对象(需要自行管理内存生命周期)
如果确实有存储指针的需求,可以在堆上分配对象,避免栈内存自动回收:
裸指针版本(需手动delete避免内存泄漏)
#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) { nums[i] = new Number(); // 堆上分配,生命周期不随循环结束终止 } std::cout << nums[1]->number << "\n"; // 使用完后手动释放内存 for (auto ptr : nums) { delete ptr; } return 0; }
智能指针版本(自动管理内存,推荐需要指针的场景使用)
#include <iostream> #include <vector> #include <memory> typedef struct Number { int number = 15; } Number; int main() { std::vector<std::unique_ptr<Number>> nums(5); for (size_t i = 0; i < nums.size(); ++i) { nums[i] = std::make_unique<Number>(); } std::cout << nums[1]->number << "\n"; // 不需要手动释放,unique_ptr离开作用域自动回收内存 return 0; }
内容的提问来源于stack exchange,提问作者laser_sex_machine
相关产品推荐
相关产品推荐

