C++智能指针上

news2025/4/25 13:41:33

一、裸指针

        “裸指针”是最基础的,直接存储内存地址的指针类型。特点:①它本身没有自动的内存管理机制:如它不会自动释放内存,也不会检查是否指向有效的内存区域;②直接操作内存地址,不进行任何的边界检查:如空指针解引用。

int main()
{
    int x = 10;
    int*p = &x;           //裸指针p指向x
    cout << *p << endl;   //输出x的值,10
    return 0;
}

1、动态内存分配:new 与 malloc 详解

        在 C++ 中,动态内存分配是指在程序运行时(而非编译时)从堆(heap)上分配内存。主要有两种方式:new/delete:C++ 的运算符       malloc/free:C 标准库函数。

①new在堆分配的内存是无名的,返回一个指向该对象的指针。

    //分配单个对象
    int* p = new int;       //p指向一个动态分配的、未初始化的无名对象
    int* p2 = new int(42);  //分配并初始化为42
    int* p3 = new int();    //值初始化,*p3=0

    //分配数组
    int* arr = new int[10];//分配10个int的数组

    //释放内存
    delete p;
    delete[] arr;

②malloc返回void*,需要强制类型转换。

    //分配内存
    int* p = (int*)malloc(sizeof(int));          //分配一个int
    int* arr = (int*)malloc(10 * sizeof(int));   //分配10个int的数组

    //释放内存
    free(p);
    free(arr);

③两者区别:

a.基本内存分配与初始化:new支持初始化;malloc不初始化,分配后必须手动赋值,否则读取是未定义的行为。

b.类对象的内存管理:new自动调用构造函数,delete自动调用析构函数;malloc只是分配内存,需要配合placement new使用,且必须手动调用析构函数。

c.数组处理:new[]和delete[]配合使用;malloc需要手动计算数组大小、初始化每个元素。

d.内存分配失败处理:new在失败时抛出异常(std::bad_alloc);malloc在失败时返回NULL/nullptr。

e.与realloc的配合:

//new没有直接对应的realloc功能,需要手动实现:
    int* arrNew = new int[5];
    int* newArrNew = new int[10];
    std::copy(arrNew, arrNew + 5, newArrNew); //将 arrNew 的前5个元素复制到 newArrNew
    delete[] arrNew;
    arrNew = newArrNew;

//malloc可以配合realloc使用
    int* arr = (int*)malloc(5 * sizeof(int));
    // 扩展内存到10个int
    int* newArr = (int*)realloc(arr, 10 * sizeof(int));
    if (newArr)
    {
        arr = newArr;
        arr[8] = 42;  //使用新分配的空间
    }
    free(arr);

2、malloc两种内存分配方式

        ①brk()方式:分配小块内存(通常是小于128KB),通过brk()系统调用会将堆顶指针向更高的内存地址移动,获取内存空间。被free释放时,并不会将内存归还给操作系统,而是将其缓冲在内存池中,供后续分配请求复用。
优点:直接操作堆,内存分配速度较快。缺点:频繁使用,堆内将产生越来越多不可用的碎片,导致“内存泄漏”。
        ②mmap()方式:当用户请求的内存较大时(通常大于128KB),mmap()在进程的虚拟地址空间中(堆和栈的中间,称为文件映射区域的地方)找一块空闲的虚拟内存。free释放时,会把内存归还给操作系统,内存得到真正释放。
缺点:向操作系统申请内存,是通过系统调用的,执行系统调用是要进入内核态的,然后回到用户态,运行态的切换会耗费不少时间。分配的内存释放都会归还给操作系统。所以每次分配的虚拟地址都是缺页状态,在第一次访问该虚拟地址的时候,就会触发缺页中断。

二、智能指针

        “智能指针”是原始指针的封装,解决了裸指针带来的内存管理问题,可以自动管理内存的生命周期。

1、unique_ptr  “独占所有权”

①三种创建方式

#include <iostream>
using namespace std;
#include <memory>

class MyClass {
public:
    MyClass() { cout << "MyClass created!" << endl; }
    MyClass(int x, double y) {}    // 带参数的构造函数
    ~MyClass() { cout << "MyClass destroyed!" << endl; }
};

int main()
{
    //创建unique_ptr的三种方式:
    //1、使用make_unique  "推荐!!!"
    unique_ptr<MyClass> ptr = make_unique<MyClass>();//函数模板必须使用函数调用运算符 () 来调用。
    auto ptr1 = make_unique<MyClass>(42, 3.14); // 正确:传递参数

    //2、使用new运算符
    unique_ptr<MyClass> ptr2(new MyClass());
    //3、使用unique_ptr的构造函数
    MyClass* rawPtr = new MyClass();
    unique_ptr<MyClass> ptr3(rawPtr);

    return 0;
}

②成员函数get()获取原始指针(裸指针)

    MyClass* rawPtr = ptr.get();  //像普通指针一样使用它

注意:get()不改变所有权,unique_ptr仍然拥有资源的所有权,并在销毁时自动释放资源,手动对rawPtr调用delete会导致双重释放,尽量避免滥用get()。

③调用成员函数和解引用

④不可以copy只可以move

不允许复制是为了保证资源管理的唯一性。如果允许就会有多个指针共享相同的资源,导致双重释放等问题。

⑤reset()清空智能指针

reset方法将智能指针指向的对象释放,并将智能指针设置为nullptr。unique_ptr是独占拥有权,因此它会立即释放资源。

⑥作函数参数,值/引用/常量引用传递/右值引用

按值传递:传递所有权。

按引用传递:

常量引用传递时,函数无法修改指针的状态。

右值引用:值传递会触发一次移动构造,右值引用直接绑定到传入的右值,没有额外移动

                  传递所有权。

⑦以值返回:优化为移动,转移所有权。

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

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

相关文章

低代码平台开发串口调试助手

项目介绍 串口调试助手是一款用于串口通信调试的工具&#xff0c;它可以帮助开发人员发送和接收串口数据&#xff0c;主要用于嵌入式开发、工业控制、物联网设备开发等领域。 主要功能包括&#xff1a; 数据收发&#xff1a;可以实时发送和接收串口数据&#xff0c;并显示在界…

怎么配置一个kubectl客户端访问多个k8s集群

怎么配置一个kubectl客户端访问多个k8s集群 为什么有的客户端用token也访问不了k8s集群&#xff0c;因为有的是把~/.kube/config文件&#xff0c;改为了~/.kube/.config文件&#xff0c;文件设置成隐藏文件了。 按照kubectl的寻找配置的逻辑&#xff0c;kubectl找不到要访问集群…

12N60-ASEMI无人机专用功率器件12N60

编辑&#xff1a;LL 12N60-ASEMI无人机专用功率器件12N60 型号&#xff1a;12N60 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 最大漏源电流&#xff1a;12A 漏源击穿电压&#xff1a;600V 批号&#xff1a;最新 RDS&#xff08;ON&#xff09;Max&#xff1a;0.68…

长城智驾重复造轮子

左手新能源&#xff0c;右手智驾&#xff0c;这是长城当下最在意的两块业务。 从去年8月首款具备高阶智能驾驶功能SUV全新蓝山上市之后&#xff0c;长城在传播端的重点就是围绕智驾、无图方案打造智驾标签。 先是在广州国际车展上&#xff0c;整个展厅只展出全新蓝山&#xf…

continue插件实现IDEA接入本地离线部署的deepseek等大模型

文章目录 前言一、IDEA安装continue二、continue部署本地大模型三、continue聊天窗口使用deepseek R1四、continue批量接入硅基流动的模型API 前言 亲爱的家人们&#xff0c;创作很不容易&#xff0c;若对您有帮助的话&#xff0c;请点赞收藏加关注哦&#xff0c;您的关注是我…

滚珠螺杆在数控机床中如何降低摩擦系数?

对数控机床这样要求加工精度高而且加工精度能保持长期稳定的设备来说是必须的&#xff0c;而且具有较低的传动阻力也同时为更高速的传动打下基础。使用滚珠螺杆&#xff0c;也是数控机床加工效率高的一个重要原因&#xff0c;为了减少数控机床的滚珠螺杆出现摩擦&#xff0c;可…

【现代深度学习技术】循环神经网络05:循环神经网络的从零开始实现

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

Python实现技能记录系统

Python实现技能记录系统 来自网络&#xff0c;有改进。 技能记录系统界面如下&#xff1a; 具有保存图片和显示功能——允许用户选择图片保存&#xff0c;选择历史记录时若有图片可预览图片。 这个程序的数据保存在数据库skills2.db中&#xff0c;此数据库由用Python 自带的…

Linux常见指令介绍下(入门级)

1. head head就和他的名字一样&#xff0c;是显示一个文件头部的内容&#xff08;会自动排序&#xff09;&#xff0c;默认是打印前10行。 语法&#xff1a;head [参数] [文件] 选项&#xff1a; -n [x] 显示前x行。 2. tail tail 命令从指定点开始将文件写到标准输出.使用t…

VIC-3D非接触全场应变测量系统用于小尺寸测量之电子元器件篇—研索仪器DIC数字图像相关技术

在5G通信、新能源汽车电子、高密度集成电路快速迭代的今天&#xff0c;电子元件的尺寸及连接工艺已进入亚毫米级竞争阶段&#xff0c;这种小尺寸下的力学性能评估对测量方式的精度有更高的要求&#xff0c;但传统应变测量手段常因空间尺寸限制及分辨率不足难以捕捉真实形变场。…

下篇:深入剖析 BLE GATT / GAP / SMP 与应用层(约5000字)

引言 在 BLE 协议栈的最上层,GAP 定义设备角色与连接管理,GATT 构建服务与特征,SMP 负责安全保障,应用层则承载具体业务逻辑与 Profile。掌握这一层,可实现安全可靠的设备发现、配对、服务交互和定制化业务。本文将详解 GAP、GATT、SMP 三大模块,并通过示例、PlantUML 时…

27、Session有什么重⼤BUG?微软提出了什么⽅法加以解决?

Session的重大BUG 1、进程回收导致Session丢失 原理&#xff1a; IIS的进程回收机制会在系统繁忙、达到特定内存阈值等情况下&#xff0c;自动回收工作进程&#xff08;w3wp.exe&#xff09;。由于Session数据默认存储在进程内存中&#xff0c;进程回收时这些数据会被清除。 …

云智融合普惠大模型AI,政务服务重构数智化路径

2025年是“十四五”收官之年&#xff0c;数字政府和政务数智化作为“数字中国”建设的重点&#xff0c;已经取得了显著成效。根据《联合国电子政务调查报告2024》&#xff0c;我国电子政务发展指数全球排名第35位&#xff0c;与2022年相比提升8个名次&#xff1b;其中&#xff…

UE5 调整字体、界面大小

文章目录 方案一 5.4 版本及以上&#xff08;推荐&#xff09;方案二 5.3 版本及以下&#xff08;推荐&#xff09;方案三 使用插件&#xff08;不推荐&#xff09; 方案一 5.4 版本及以上&#xff08;推荐&#xff09; 进入 编辑 > 编辑器偏好设置&#xff0c;如下图所示&…

抽象类相关

抽象类的定义 抽象类 是一种特殊的类&#xff0c;它不能被实例化&#xff0c;只能作为基类来派生出具体类。抽象类至少包含一个纯虚函数 。纯虚函数是在函数原型前加上 0 的虚函数&#xff0c;表示该函数没有具体实现&#xff0c;必须由派生类来实现。 抽象类的作用 提供统…

【UVM项目实战】异步fifo—uvm项目结构以及uvm环境搭建

本文章同步到我的个人博客网站&#xff1a;ElemenX-King&#xff1a;【UVM项目实战】异步fifo—uvm项目结构以及uvm环境搭建 希望大家能使用此网站来进行浏览效果更佳&#xff01;&#xff01;&#xff01; 目录 一、异步FIFO1.1 异步FIFO的定义1.2 亚稳态1.3 异步FIFO关键技术…

【通关函数的递归】--递归思想的形成与应用

目录 一.递归的概念与思想 1.定义 2.递归的思想 3.递归的限制条件 二.递归举例 1.求n的阶乘 2.顺序打印一个整数的每一位 三.递归与迭代 前言:上篇博文分享了扫雷游戏的实现&#xff0c;这篇文章将会继续分享函数的递归相关知识点&#xff0c;让大家了解并掌握递归的思…

【FAQ】针对于消费级NVIDIA GPU的说明

概述 本文概述 HP Anyware 在配备消费级 NVIDIA GPU 的物理工作站上的关​​键组件、安装说明和重要注意事项。 注意&#xff1a;本文档适用于 NVIDIA 消费级 GPU。NVIDIA Quadro 和 Tesla GPU 也支持 HP Anyware 在公有云、虚拟化或物理工作站环境中运行。请参阅PCoIP Graphi…

MyBatis操作数据库---从入门到理解

文章目录 关于MyBatis操作数据库MyBatis⼊⻔&#xff08;使用&#xff09;Mybatis操作数据库的步骤&#xff1a;配置数据库连接字符串使⽤MyBatis完成简单的增删改查操作注解xml 单元测试开启驼峰命名(推荐) 打印日志 关于MyBatis操作数据库 在之前的学习,我们了解到web应⽤程…

【HFP】蓝牙语音通话控制深度解析:来电拒接与通话终止协议

目录 一、来电拒接的核心流程与信令交互 1.1 拒接场景的分类与触发条件 1.2 HF 端拒接流程 1.3 AG 端拒接流程 二、通话终止流程&#xff1a;主动断开与异常中断 2.1 终止场景的界定 2.2 HF 端终止流程 2.3 AG 端终止流程 三、信令协议的核心要素&#xff1a;AT 命令与…