C++之优化Linux内核结构体用智能指针std::unique_ptr与std::make_unique分配内存总结(二百六十五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:C++之结构体使用智能指针std::unique_ptr与std::make_unique分配内存总结

2.结构体使用智能指针std::unique_ptr与std::make_unique分配内存介绍

  • 在C++中,结构体(struct)是一种用户定义的数据类型,它允许我们组合多个不同类型的数据项,形成一个单一的复合数据类型。当结构体中包含动态分配的内存时,管理这些内存就变得尤为重要。std::unique_ptr和std::make_unique是C++11引入的两个智能指针工具,它们能够帮助我们自动管理这些动态分配的内存。

  • 使用std::unique_ptr管理结构体内存

  • std::unique_ptr是一个独占所有权的智能指针,当指向的结构体不再需要时,unique_ptr会自动删除它,从而避免了手动调用delete的繁琐和潜在的内存泄漏问题。

  • 下面是一个例子,展示如何使用std::unique_ptr来管理结构体的内存:

struct MyStruct {  int x;  double y;  // 其他成员...  
};  int main() {  // 使用std::unique_ptr动态分配MyStruct对象  std::unique_ptr<MyStruct> ptr(new MyStruct{42, 3.14});  // 使用ptr  std::cout << ptr->x << ", " << ptr->y << std::endl;  // 当ptr离开作用域时,它所指向的MyStruct对象会被自动删除  // 不需要手动调用delete  
}
  • 使用std::make_unique分配结构体内存std::make_unique是一个函数模板,它用于创建一个std::unique_ptr实例,并自动分配内存。使用make_unique更加安全,因为它避免了直接使用new可能引发的异常安全性问题。

  • 以下是如何使用std::make_unique来分配结构体的内存:

struct MyStruct {  int x;  double y;  // 其他成员...  
};  int main() {  // 使用std::make_unique创建指向MyStruct的unique_ptr  auto ptr = std::make_unique<MyStruct>(42, 3.14);  // 使用ptr  std::cout << ptr->x << ", " << ptr->y << std::endl;  // 当ptr离开作用域时,它所指向的MyStruct对象会被自动删除  
}
  • 在这个例子中,我们假设MyStruct有一个接受两个参数的构造函数。std::make_unique直接调用这个构造函数来初始化MyStruct对象,并返回一个指向该对象的unique_ptr。

  • 通过使用std::unique_ptr和std::make_unique,我们可以确保结构体的内存得到正确的管理,避免了手动管理内存所带来的风险和复杂性。这是现代C++编程中推荐的内存管理实践之一。

3.代码实例

<1>.v1.0 非智能指针版本

#include <iostream>
#include <memory>
#include <string>struct file {void *private_data;
};struct binder_context {int binder_context_mgr_node;const char *name;
};struct binder_proc {int proc;struct binder_context *context;
};static int binder_ioctl_set_ctx_mgr(struct file *filp){struct binder_proc *proc = (struct binder_proc *)filp->private_data;struct binder_context *context = proc->context;context->binder_context_mgr_node = 33;printf("xxx--------------->%s(), line = %d, binder_context_mgr_node = %d\n",__FUNCTION__,__LINE__,proc->context->binder_context_mgr_node);return 0;
}int main(){struct file *filp;struct binder_proc *proc = (struct binder_proc*)malloc(sizeof(struct binder_proc));proc->context = (struct binder_context*)malloc(sizeof(struct binder_context));proc->context->binder_context_mgr_node = -1;//1.初始化结构体struct filefilp = (struct file*)malloc(sizeof(struct file));// 使用 std::unique_ptr 来动态分配内存//std::unique_ptr<struct file> filp = std::make_unique<struct file>();filp->private_data = proc;//2.binder_ioctl_set_ctx_mgr(filp);printf("xxx--------------->%s(), line = %d, binder_context_mgr_node = %d\n",__FUNCTION__,__LINE__,((struct binder_proc *)(filp->private_data))->context->binder_context_mgr_node);free(proc->context);free(proc);
}

<2>.v2.0 智能指针版本

#include <iostream>
#include <memory>
#include <string>struct file {void* private_data;
};struct binder_context {int binder_context_mgr_node;const char* name;
};struct binder_proc {int proc;std::unique_ptr<binder_context> context; // 使用 std::unique_ptr 管理内存
};static int binder_ioctl_set_ctx_mgr(file* filp) {binder_proc* proc = static_cast<binder_proc*>(filp->private_data);binder_context* context = proc->context.get(); // 获取原始指针context->binder_context_mgr_node = 33;printf("xxx--------------->%s(), line = %d, binder_context_mgr_node = %d\n",__FUNCTION__,__LINE__,proc->context->binder_context_mgr_node);return 0;
}int main() {//v1.0//auto filp = std::make_unique<file>();//v2.0//std::unique_ptr<struct file> filp(new file()); // 使用 std::unique_ptr 管理内存//v3.0//std::unique_ptr<struct file> filp(std::make_unique<file>());//v4.0//std::unique_ptr<struct file> filp = std::make_unique<file>();//v5.0std::unique_ptr<struct file> filp = std::make_unique<struct file>();//std::unique_ptr<binder_proc> proc(new binder_proc());std::unique_ptr<binder_proc> proc = std::make_unique<struct binder_proc>();proc->context = std::make_unique<binder_context>(); // 使用 std::make_unique 分配内存proc->context->binder_context_mgr_node = -1;filp->private_data = proc.get();binder_ioctl_set_ctx_mgr(filp.get());printf("xxx--------------->%s(), line = %d, binder_context_mgr_node = %d\n",__FUNCTION__,__LINE__,static_cast<binder_proc*>(filp->private_data)->context->binder_context_mgr_node);// 不需要显式调用 delete,因为智能指针会在超出作用域时自动释放内存return 0;
}

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

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

相关文章

搜索二叉树详细介绍C++

文章目录 前言一、搜索二叉树介绍二、二叉搜索树实现1.查找2.插入3.删除 三、二叉搜索树递归实现1.查找2.插入3.删除 四、二叉搜索树性能分析五、二叉搜索树应用1.K模型2.KV模型 总结 前言 在本篇文章中&#xff0c;我们将会学到数据结构中有关二叉树中一种特殊的结构-----搜索…

PCB三大走线,如何高效率检查?

在PCB设计中&#xff0c;走线的布局与检查是至关重要的环节。按照走线类型&#xff0c;可分为直角走线、差分走线及蛇形线&#xff0c;如何针对这三种走线方式进行高效率检查&#xff0c;去也报电路的稳定性和可靠性&#xff1f; 1、直角走线 容性负载&#xff1a;观察直角拐角…

2024.4.2每日一题

LeetCode 所有可能的真二叉树 题目链接&#xff1a;894. 所有可能的真二叉树 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个整数 n &#xff0c;请你找出所有可能含 n 个节点的 真二叉树 &#xff0c;并以列表形式返回。答案中每棵树的每个节点都必须符合 Nod…

前端学习<三>CSS进阶——03-网页设计和开发中,那些困扰大神的关于字体的知识

前言 我周围的码农当中&#xff0c;有很多是技术大神&#xff0c;却常常被字体这种简单的东西所困扰。 这篇文章&#xff0c;我们来讲一讲关于字体的常识。这些常识所涉及到的问题&#xff0c;有很强的可操作性&#xff0c;都是在实际业务中真实遇到的&#xff0c;都是需要开…

超全!2024最新 注册信息安全工程师CISP认证培训攻略大全

随着信息化的全面纵深发展&#xff0c;各单位对信息系统的依赖程度及系统安全运行需求的日益提升&#xff0c;对信息系统管理及运维人员的信息安全保障技术能力和综合素质也提出了更高的要求。 国家注册信息安全专业人员(CISP)是网络系统建设、运行和应用管理的技术部门必备的…

4.2 day3 FreeRTOS

1.总结任务调度算法之间的区别&#xff0c;重新实现一遍任务调度算法的代码。 抢占式调度&#xff1a;高优先级的任务可以打断低优先级任务的执行。抢占式调度适用于任务优先级不同的任务。 时间片轮转&#xff1a;相同优先级的任务有相同的时间片&#xff08;1ms&#xff09…

(十一)RabbitMQ及SpringAMQP

1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;…

Linux:入门篇

文章目录 前言1. Linuxd的安装环境2.Linux的简单介绍2.1 新建目录2.2 新建文件 3.指令到底是什么&#xff1f;4.shell命令以及运行原理5.总结 前言 很多人对于Linux的学习总是感觉无法下手&#xff0c;不知道从何开始学习&#xff0c;相信这篇文章将会为你提供一个清晰的思路。…

NXP-S32DS软件安装

文章目录 一、安装包获取二、S32DS安装三、芯片插件安装 一、安装包获取 登录NXP官网&#xff0c;进入软件目录https://www.nxp.com/ 下载S32DS软件和RTD驱动库&#xff0c;并安装S32DS软件。 单击“S32DS.3.5_b220726_win32.x86_64.exe”下载该软件 点击“License Keys”&…

【PythonGIS】Python实现批量导出面矢量要素(单个多面矢量->多个单面矢量)

可怜的我周六还在工作&#xff0c;已经很久没更新过博客了&#xff0c;今天正好有空就和大家分享一下。今天给大家带来的是使用Python将包含多个面要素/线要素的矢量批量导出单个要素的矢量&#xff0c;即一个要素一个矢量文件。之前写过多个矢量文件合并成一个矢量文件的博文&…

Linux文件与进程交互的窥探者lsof

lsof 是一个 Linux 和 UNIX 系统中的实用工具&#xff0c;用于列出系统中打开文件的所有信息。这个名字代表 “List Open Files”&#xff0c;但它也可以显示进程相关的其他信息&#xff0c;如&#xff1a; 打开的文件描述符列表 打开网络连接的列表 被进程使用的信号和内核对…

新手学python还是c?

考虑到个人情况和职业规划是非常重要的。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。 Python作为初学者入门语言…