简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
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 file
filp = (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.0
std::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;
}