如何访问打印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的循环内直接删除元素,会导致后续元素前移、索引错位,容易引发越界或漏遍历问题。
正确实现方案
两个需求的实现逻辑:
- 访问
unique_ptr存储的数值和普通指针一致,直接解引用*ptr即可; - 删除指定索引元素直接调用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
相关产品推荐
相关产品推荐

