使用unique_ptr防文件操作内存泄漏的小技巧

链接:https://www.bilibili.com/video/BV12K411p7GC
本文只是对视频内容归纳整理。

假设从Linux系统的某文件读取5个字符,可写成:

#include <fcntl.h>	 // ::open()
#include <unistd.h>	 // ::close()
#include <stdio.h>

int main()
{
	int fd = ::open("test.cc", O_RONLY, 0);
	if (fd == -1) {
		::puts("open failure");
		return 1;
	}
	
	char str[6] = {};
	long nread = ::read(fd, str, sizeof(str-1)); // 读5个字符+'/0'
	if (nread < 0) {
		::puts("read failure");
		::close(fd);
		return 1;
	}
	
	printf("str = %s\n", str);
	// we can do something here
	
	::close(fd);
}

但是这个程序存在潜在的内存泄漏,位置在:

printf("str = %s\n", str);
// we can do something here

如果此时printf抛出异常或do something导致程序提前返回,则无法执行::close(fd)。那么文件描述符就没有被正确关闭。
解决方案是使用智能指针来管理对象的作用域,但fd是整数,而非指针,怎么使用智能指针呢?于是有如下技巧:

#include <fcntl.h>	 // ::open()
#include <unistd.h>	 // ::close()
#include <stdio.h>
#include <memory>

int main()
{
	int fd = ::open("test.cc", O_RONLY, 0);
	if (fd == -1) {
		::puts("open failure");
		return 1;
	}
	
	// 使用unique_ptr管理内存分配对象的作用域
	// 这时候我们就可以把程序中其他的::close语句删除了
	::std::unique_ptr<int, void (*)(int*)> guard(
		&fd, [](int *p) { ::close(*p); });
	
	char str[6] = {};
	long nread = ::read(fd, str, sizeof(str-1)); // 读5个字符+'/0'
	if (nread < 0) {
		::puts("read failure");
		return 1;
	}
	
	printf("str = %s\n", str);
	// we can do something here
}

即保证了内存安全,又不用到处写::close语句,是不是很香?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值