【std::vector】vector<T*>与vector<T>*

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

      • 一、先回答第一个问题:`vector<int*>` 类型拷贝前,是否需要遍历一遍元素 `delete`?
        • 1. 核心前提:`vector<int*>` 只存指针,不管理指针指向的内存(浅拷贝特性)
        • 2. 分情况讨论:是否需要`delete`
          • 情况1:指针指向**栈内存**(或全局/静态内存)
          • 情况2:指针指向**堆内存**(`new int/ new int[]`分配的)
        • 3. 优化方案:用智能指针代替裸指针(推荐)
      • 二、`vector<int*>` 与 `vector<int>*` 的对比
        • 1. 栈堆分布:分层拆解(关键:区分“对象本身”和“对象指向/存储的内容”)
          • (1)`vector<int*>` 的栈堆分布(三层结构)
          • (2)`vector<int>*` 的栈堆分布(三层结构)
        • 2. 适用场景
          • (1)`vector<int*>` 的使用场景
          • (2)`vector<int>*` 的使用场景
        • 3. 核心区别总结
      • 三、补充示例代码
        • 1. `vector<int*>` 的内存管理示例(裸指针版,需手动delete)
        • 2. `vector<int>*` 的示例(现代C++推荐用unique_ptr)

一、先回答第一个问题:vector<int*>类型拷贝前,是否需要遍历一遍元素delete

结论:不一定,核心取决于vector<int*>中存储的指针指向的内存类型,以及谁是这些内存的所有者

1. 核心前提:vector<int*>只存指针,不管理指针指向的内存(浅拷贝特性)

vector<int*>中的元素是**int*类型的指针**,vector的赋值/拷贝操作只会做浅拷贝:即只复制指针的(也就是内存地址),不会复制指针指向的int对象,也不会自动管理指针指向的内存。

因此,vector的默认行为不会帮你delete指针指向的内存——这部分内存的生命周期需要程序员手动控制。

2. 分情况讨论:是否需要delete
情况1:指针指向栈内存(或全局/静态内存)

如果vector<int*>中的指针指向栈上的int(比如int a = 10; int* p = &a;),绝对不能delete
栈内存由编译器自动管理,delete栈指针会导致未定义行为(程序崩溃、内存错乱等)。

情况2:指针指向堆内存new int/ new int[]分配的)

如果指针是通过new/new[]分配的堆内存(比如int* p = new int(5);),则需要分场景:

  • 场景A:当前vector是该堆内存的唯一所有者(没有其他指针指向这块内存):
    在拷贝(赋值、清空、析构)前,必须遍历vector执行delete(或delete[],否则指针指向的堆内存会成为“孤儿内存”,导致内存泄漏
  • 场景B:堆内存被多个指针共享(比如其他变量也指向这块内存):
    不能直接delete,否则会导致其他指针变成悬垂指针(指向已释放的内存),后续访问会触发未定义行为。
3. 优化方案:用智能指针代替裸指针(推荐)

手动delete裸指针容易出错(漏删、重复删、删栈指针),C++11起推荐用智能指针unique_ptr/shared_ptr)代替裸指针,智能指针会自动管理内存,无需手动delete

// 用unique_ptr(独占所有权)代替裸指针,自动释放内存vector<unique_ptr<int>>v1;v1.push_back(make_unique<int>(5));v1.push_back(make_unique<int>(6));// 赋值时,unique_ptr会自动转移所有权,旧的unique_ptr会自动释放内存(无需手动delete)vector<unique_ptr<int>>v2;v1=v2;// 旧的v1元素(unique_ptr)会被销毁,自动delete指向的int

二、vector<int*>vector<int>*的对比

首先明确两者的类型本质,这是理解后续内容的关键:

类型本质含义
vector<int*>一个vector容器对象,其存储的元素是int*类型的指针(指向int的指针)
vector<int>*一个指针变量,其指向的是vector<int>类型的容器对象

接下来从栈堆分布使用场景核心区别三个维度详细分析。

1. 栈堆分布:分层拆解(关键:区分“对象本身”和“对象指向/存储的内容”)

C++中内存分布的核心规则:局部变量(非static)在栈上,new/malloc分配的在堆上。但vector的底层特性是:无论vector对象本身在栈还是堆,其内部存储的元素数组永远在堆上(vector的动态数组是动态分配的)。

(1)vector<int*>的栈堆分布(三层结构)
  • 第一层:vector<int*>对象本身
    取决于声明方式:
    • 局部变量:vector<int*> v;→ 对象本身在上(栈帧中)。
    • 动态分配:vector<int*> *pv = new vector<int*>;→ 对象本身在上(new分配)。
  • 第二层:vector<int*>内部的元素数组(存储int*指针的数组)
    无论vector对象本身在栈还是堆,这部分数组永远在上(vector的底层实现决定)。
  • 第三层:int*指针指向的int对象
    由指针的赋值决定:
    • 指向栈:int a = 10; int* p = &a;int在栈上。
    • 指向堆:int* p = new int(10);int在堆上。
(2)vector<int>*的栈堆分布(三层结构)
  • 第一层:vector<int>*指针变量本身
    取决于声明方式:
    • 局部变量:vector<int>* pv;→ 指针变量本身在上(栈帧中,占用8字节(64位)存储内存地址)。
    • 动态分配:vector<int>** ppv = new vector<int>*;→ 指针变量本身在上(极少用)。
  • 第二层:指针指向的vector<int>对象
    几乎只能在堆上(否则无意义,且易出错):
    • 正确用法:pv = new vector<int>;vector<int>对象在堆上。
    • 错误用法:vector<int> v; pv = &v;pv指向栈上的vector,若v先销毁,pv会变成悬垂指针(后续访问崩溃)。
  • 第三层:vector<int>对象内部的int元素数组
    永远在上(vector的底层特性)。
2. 适用场景
(1)vector<int*>的使用场景

用于需要存储多个指向int的指针的场景,常见情况:

  • 场景1:管理一组独立的动态int对象/数组
    比如需要存储多个大小不同的int数组(int* arr1 = new int[5]; int* arr2 = new int[10];),可以用vector<int*>存储这些数组的首地址。
  • 场景2:与C风格代码交互
    C函数常返回int*类型的数组(如int* get_data()),可以用vector<int*>接收和管理这些指针。
  • 场景3:存储指向不同内存位置的int
    比如同时指向栈上的int、全局int、堆上的int

注意:尽量用vector<unique_ptr<int>>/vector<shared_ptr<int>>代替裸指针的vector<int*>,避免手动管理内存的风险。

(2)vector<int>*的使用场景

这种用法在现代C++中逐渐减少,仅在特定场景下使用:

  • 场景1:大型vector对象,避免栈溢出
    栈空间有限(通常几MB),如果要创建存储百万级intvector<int>,直接在栈上声明(vector<int> v(1000000);)会导致栈溢出,此时可以用vector<int>* pv = new vector<int>(1000000);(将vector对象放在堆上)。
  • 场景2:动态控制vector的生命周期
    比如需要让vector对象的生命周期跨越函数调用(如作为全局指针,在函数中创建,程序结束时销毁),或根据条件动态创建/销毁vector
  • 场景3:旧代码中作为函数参数传递(现代C++不推荐)
    早期C++中,为了避免函数参数传递vector时的拷贝开销,会用vector<int>*传递指针;但现代C++推荐用引用(vector<int>&const引用(const vector<int>&,效率更高且更安全。

注意:vector<int>*的裸指针容易出现忘记delete(内存泄漏)或悬垂指针(访问崩溃),现代C++推荐用unique_ptr<vector<int>>(独占所有权)或shared_ptr<vector<int>>(共享所有权)代替。

3. 核心区别总结
维度vector<int*>vector<int>*
类型本质vector容器(存储int*指针)指针(指向vector<int>容器)
存储的核心内容多个int*指针(地址)一个vector<int>容器的地址
内存泄漏风险点裸指针指向的堆内存未delete指向的vector<int>对象未delete
现代C++替代方案vector<unique_ptr<int>>/shared_ptr<int>unique_ptr<vector<int>>/shared_ptr<vector<int>>
常用程度偶尔用(需指针场景)极少用(现代C++推荐引用/移动语义)

三、补充示例代码

1.vector<int*>的内存管理示例(裸指针版,需手动delete)
#include<iostream>#include<vector>usingnamespacestd;intmain(){vector<int*>v1;// 向v1中添加堆内存的int指针v1.push_back(newint(1));v1.push_back(newint(2));// 拷贝前:遍历delete原有元素(避免内存泄漏)for(int*p:v1){deletep;// 释放指针指向的堆内存}v1.clear();// 清空vector中的指针(可选,赋值时会自动销毁原有元素)// 赋值新的vector<int*>vector<int*>v2;v2.push_back(newint(5));v1=v2;// 程序结束前:再次遍历delete v1中的元素for(int*p:v1){deletep;}return0;}
2.vector<int>*的示例(现代C++推荐用unique_ptr)
#include<iostream>#include<vector>#include<memory>// 智能指针头文件usingnamespacestd;intmain(){// 旧写法:裸指针,需手动deletevector<int>*pv1=newvector<int>{1,2,3};cout<<pv1->size()<<endl;// 访问vector的成员需用->deletepv1;// 必须delete,否则内存泄漏// 现代C++写法:unique_ptr,自动释放unique_ptr<vector<int>>pv2=make_unique<vector<int>>({4,5,6});cout<<pv2->size()<<endl;// 无需delete,unique_ptr析构时自动释放vector对象return0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1143016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PDF-Extract-Kit前端定制:WebUI界面修改教程

PDF-Extract-Kit前端定制&#xff1a;WebUI界面修改教程 1. 引言 1.1 工具背景与开发初衷 PDF-Extract-Kit 是一款由开发者“科哥”主导构建的开源 PDF 智能提取工具箱&#xff0c;旨在为科研人员、教育工作者和文档处理从业者提供一套完整的自动化文档解析解决方案。该工具…

终极指南:3招彻底解决百度网盘下载龟速问题

终极指南&#xff1a;3招彻底解决百度网盘下载龟速问题 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘下载速度慢如蜗牛而苦恼吗&#…

Multisim下载前必读:版本选择与系统要求全面讲解

Multisim下载前必读&#xff1a;如何选对版本、配好电脑&#xff0c;一次安装成功&#xff1f; 你是不是也经历过这样的场景&#xff1f; 兴冲冲地打开浏览器搜索“Multisim下载”&#xff0c;点进官网准备安装&#xff0c;结果发现&#xff1a; 下下来的版本打不开、装到一半…

STM32CubeMX打不开:权限配置错误的核心要点

STM32CubeMX打不开&#xff1f;别急着重装&#xff0c;先看看权限这道坎 你有没有遇到过这样的情况&#xff1a;刚配好开发环境&#xff0c;兴冲冲双击桌面的 STM32CubeMX 图标&#xff0c;结果——什么都没发生&#xff1f; 任务管理器里 javaw.exe 闪了一下就消失&…

LeRobot SO-101协作机械臂:从零开始的完整搭建指南

LeRobot SO-101协作机械臂&#xff1a;从零开始的完整搭建指南 【免费下载链接】lerobot &#x1f917; LeRobot: State-of-the-art Machine Learning for Real-World Robotics in Pytorch 项目地址: https://gitcode.com/GitHub_Trending/le/lerobot 还在为复杂的机器人…

Winlator模拟器性能优化:60帧畅玩《GTA V》终极解决方案

Winlator模拟器性能优化&#xff1a;60帧畅玩《GTA V》终极解决方案 【免费下载链接】winlator Android application for running Windows applications with Wine and Box86/Box64 项目地址: https://gitcode.com/GitHub_Trending/wi/winlator 你是否曾在Android设备上…

PKHeX自动合法性插件终极指南:从入门到精通全解析

PKHeX自动合法性插件终极指南&#xff1a;从入门到精通全解析 【免费下载链接】PKHeX-Plugins Plugins for PKHeX 项目地址: https://gitcode.com/gh_mirrors/pk/PKHeX-Plugins 还在为宝可梦数据合法性验证而头疼吗&#xff1f;PKHeX自动合法性插件正是解决这一问题的利…

TouchGal:Galgame爱好者的终极社区体验完整指南

TouchGal&#xff1a;Galgame爱好者的终极社区体验完整指南 【免费下载链接】kun-touchgal-next TouchGAL是立足于分享快乐的一站式Galgame文化社区, 为Gal爱好者提供一片净土! 项目地址: https://gitcode.com/gh_mirrors/ku/kun-touchgal-next 在当前数字时代&#xff…

Waydroid架构解析:基于Linux容器的Android系统实现原理

Waydroid架构解析&#xff1a;基于Linux容器的Android系统实现原理 【免费下载链接】waydroid Waydroid uses a container-based approach to boot a full Android system on a regular GNU/Linux system like Ubuntu. 项目地址: https://gitcode.com/gh_mirrors/wa/waydroid…

Waydroid容器化Android系统在Linux环境中的深度部署指南

Waydroid容器化Android系统在Linux环境中的深度部署指南 【免费下载链接】waydroid Waydroid uses a container-based approach to boot a full Android system on a regular GNU/Linux system like Ubuntu. 项目地址: https://gitcode.com/gh_mirrors/wa/waydroid 技术…

Cursor AI编程工具永久免费使用完整教程

Cursor AI编程工具永久免费使用完整教程 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youve reached your trial request limit. / Too …

明日方舟基建自动化革命:Arknights-Mower如何将繁琐管理变为轻松游戏

明日方舟基建自动化革命&#xff1a;Arknights-Mower如何将繁琐管理变为轻松游戏 【免费下载链接】arknights-mower 《明日方舟》长草助手 项目地址: https://gitcode.com/gh_mirrors/ar/arknights-mower 你是否曾经计算过&#xff0c;在《明日方舟》中每天花费多少时间…

PDF-Extract-Kit实战:PDF文档自动翻译系统搭建

PDF-Extract-Kit实战&#xff1a;PDF文档自动翻译系统搭建 1. 引言&#xff1a;从智能提取到自动翻译的工程闭环 在学术研究、技术文档和跨国协作场景中&#xff0c;PDF文档的跨语言处理需求日益增长。传统的翻译工具往往无法准确保留原始文档的版式结构&#xff0c;导致表格…

e1547:解锁e621社区的全新浏览体验

e1547&#xff1a;解锁e621社区的全新浏览体验 【免费下载链接】e1547 A sophisticated e621 browser 项目地址: https://gitcode.com/gh_mirrors/e1/e1547 想要更轻松地探索e621社区内容吗&#xff1f;e1547这款开源应用将彻底改变你的浏览方式&#xff01;作为一款专为…

FontForge免费字体设计工具完整指南:从零开始打造专业字体

FontForge免费字体设计工具完整指南&#xff1a;从零开始打造专业字体 【免费下载链接】fontforge Free (libre) font editor for Windows, Mac OS X and GNULinux 项目地址: https://gitcode.com/gh_mirrors/fo/fontforge 还在为找不到合适的字体而烦恼吗&#xff1f;想…

ImageToSTL终极指南:快速免费将图片转换为3D打印模型

ImageToSTL终极指南&#xff1a;快速免费将图片转换为3D打印模型 【免费下载链接】ImageToSTL This tool allows you to easily convert any image into a 3D print-ready STL model. The surface of the model will display the image when illuminated from the left side. …

超详细版:ESP32驱动智能LED灯带全过程

用ESP32点亮你的智能灯带&#xff1a;从原理到实战的完整指南你有没有想过&#xff0c;家里的氛围灯为什么能随着音乐跳动&#xff1f;或者手机一点&#xff0c;整面墙的灯光就变成梦幻星空&#xff1f;这些炫酷效果的背后&#xff0c;其实离不开一个“小身材、大能量”的组合—…

PDF-Extract-Kit性能对比:CPU vs GPU处理效率测试

PDF-Extract-Kit性能对比&#xff1a;CPU vs GPU处理效率测试 1. 引言 1.1 技术背景与选型需求 在当前AI驱动的文档智能处理领域&#xff0c;PDF内容提取已成为科研、教育、出版等行业的重要基础能力。传统的OCR工具往往只能完成简单的文本识别&#xff0c;而现代文档中包含…

【实战指南】FontForge字体设计:从零到精通的全流程创意工作流

【实战指南】FontForge字体设计&#xff1a;从零到精通的全流程创意工作流 【免费下载链接】fontforge Free (libre) font editor for Windows, Mac OS X and GNULinux 项目地址: https://gitcode.com/gh_mirrors/fo/fontforge 在数字化设计浪潮中&#xff0c;开源字体编…

PDF-Extract-Kit与PaddleOCR整合:提升文字识别准确率

PDF-Extract-Kit与PaddleOCR整合&#xff1a;提升文字识别准确率 1. 引言&#xff1a;PDF智能提取的技术挑战与解决方案 在数字化办公和学术研究中&#xff0c;PDF文档的自动化处理已成为刚需。然而&#xff0c;传统OCR工具在面对复杂版式、数学公式、表格结构时往往力不从心…