You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 18:54:04