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

如何访问打印unique_ptr值并删除vector中指定元素避免段错误

问题根因
  • 你代码里的地址重复、内存释放报错问题,核心是错误将栈上局部变量的地址交给了std::unique_ptr管理:
    • 循环内的int x(i)是栈分配的局部变量,作用域仅限单次循环迭代,每次迭代结束x就会被自动回收,且栈上同一块内存会被反复复用给每次循环的x,所以打印出的5个指针地址完全一致。
    • std::unique_ptr默认会对持有的指针执行delete释放操作,但栈内存不属于堆分配内存,不能用delete释放,等vector销毁、unique_ptr尝试释放这块栈地址时,就会触发munmap_chunk(): invalid pointer报错。
  • 另外如果在正向遍历vector的循环内直接删除元素,会导致后续元素前移、索引错位,容易引发越界或漏遍历问题。
正确实现方案

两个需求的实现逻辑:

  1. 访问unique_ptr存储的数值和普通指针一致,直接解引用*ptr即可;
  2. 删除指定索引元素直接调用vector的erase方法,传入对应位置的迭代器,删除后vector大小会自动缩减,不需要手动调整。
#include <memory>
#include <vector>
#include <iostream>

int main()
{
    std::vector<std::unique_ptr<int>> vec;

    for (int i = 0; i < 5; i++) {
        // 用std::make_unique在堆上分配内存,交给智能指针管理,禁止传入栈变量地址
        vec.push_back(std::make_unique<int>(i));
    }
    
    std::cout << "删除前元素列表:" << std::endl;
    for (size_t i = 0; i < vec.size(); i++) {
        // 解引用unique_ptr打印存储的整数值
        std::cout << "值:" << *vec.at(i) << " 内存地址:" << vec.at(i).get() << std::endl;
    }

    // 删除索引为2的第3个元素
    vec.erase(vec.begin() + 2);

    std::cout << "\n删除后vector大小:" << vec.size() << std::endl;
    std::cout << "删除后元素列表:" << std::endl;
    for (size_t i = 0; i < vec.size(); i++) {
        std::cout << "值:" << *vec.at(i) << " 内存地址:" << vec.at(i).get() << std::endl;
    }
      
    return 0;
}
运行说明
  • 代码运行后每个智能指针持有的内存地址互不重复,删除前打印值为0、1、2、3、4;
  • 删除索引2的元素后vector大小自动变为4,剩余元素值为0、1、3、4;
  • 全程不会触发段错误或内存释放错误,所有堆内存会被智能指针自动回收,无内存泄漏。

如果编译环境不支持C++14及以上版本(没有std::make_unique),可以将入栈语句替换为vec.push_back(std::unique_ptr<int>(new int(i)));,功能完全一致。

内容的提问来源于stack exchange,提问作者Rose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:39:36