c语言智能指针 附完整示例代码
是的,你没有看错,
不是c++不是c#,
就是你认识的那个c语言。
在很长一段时间里,c的内存管理问题,
层出不穷,不是编写的时候特别费劲繁琐,
就是碰到内存泄漏排查的各种困难,
特别在多线程环境下,就难上加难了,
诸如此类的老大难问题。
c++用它的RAII机制妥妥影响了一代程序员。
RAII大概介绍下,就不做科普,
有需要的同学,百度一下了解细节。
什么是RAII
资源获取即初始化 (Resource Acquisition Is Initialization, RAII),RAII是一种资源管理机制,资源的有效期与持有资源的对象生命期严格绑定,即由对象的构造函数完成资源的分配,由析构函数完成资源的释放,总结一句话就是 用对象来管理资源
RAII实现原理
当一个对象离开作用域的时候就会被释放,会调用这个对象类的析构函数,这都是自动管理的,不需要我们手动调用。所以我们可以把资源封装到类的内部,当需要用资源的时候初始化对象即可,当对象被释放的时候资源也会被释放
当你写了多年c代码,你是多么渴望有这么一个东西可以给到你。
众望所归,终于gcc编译器开了个小灶,留了一个后门造福c程序员。
详情见:
https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
主要看这个:
cleanup (cleanup_function)
The cleanup attribute runs a function when the variable goes out of scope. This attribute can only be applied to auto function scope variables; it may not be applied to parameters or variables with static storage duration. The function must take one parameter, a pointer to a type compatible with the variable. The return value of the function (if any) is ignored.
If -fexceptions is enabled, then cleanup_function is run during the stack unwinding that happens during the processing of the exception. Note that the cleanup attribute does not allow the exception to be caught, only to perform an action. It is undefined what happens if cleanup_function does not return normally.
这个cleanup机制,用起来,妥妥就是一个c的析构函数了。
没有必要造轮子,轮子已经造好了。
libcsptr提供了常用智能指针的封装,
unique_ptr, shared_ptr ,绝对是够用了。
项目地址:
https://github.com/Snaipe/libcsptr
花了点小时间编写示例代码,造福大家。
顺手解决vs的编译问题。
另外说一下,vs不是gcc,没有cleanup 可以实现这个功能。
不过可以通过安装llvm在vs里选择llvm编译进行编译。
到https://llvm.org/releases/download.html
下载后安装,再启动vs就可以看到编译器选项了。
贴个图上来,可参照一下。

选好之后,就可以玩起来一些clang特性了。
完整示例代码:
#include <stdio.h>
#include "csptr_smart_ptr.h" struct BufferBody {
char *buffer;
size_t size;
}; static void callback_dtor(void *ptr, void *meta) {
(void) meta;
struct BufferBody *ctx = ptr;
if (ctx->buffer != NULL)
free(ctx->buffer);
} struct BufferBody *write_buffer(const char *bufbody, size_t init_body_len) {
smart struct BufferBody *ctx = shared_ptr(struct BufferBody, { }, callback_dtor);
if (!ctx) // failure to allocate
return NULL; // nothing happens, destructor is not called if (ctx->buffer == NULL) {
ctx->buffer = malloc(init_body_len);
if (ctx->buffer != NULL)
ctx->size = init_body_len;
} else {
if (ctx->size < init_body_len) {
ctx->buffer = realloc(ctx->buffer, init_body_len);
if (ctx->buffer != NULL)
ctx->size = init_body_len;
}
}
size_t buflen = strlen(bufbody);
if (ctx->size > buflen)
memcpy(ctx->buffer, bufbody, buflen);
return sref(ctx); // a new reference on bufCtx is returned, it does not get destoyed
} void do_something(size_t init_body_len) {
smart struct BufferBody *ctx = write_buffer("hello smart ptr.", init_body_len);
printf("%s \n", ctx->buffer);
// ctx is destroyed here
} int main(void) {
printf("Smart pointers for the (GNU) C\n");
printf("blog: http://cpuimage.cnblogs.com/\n");
printf("tips: u can use llvm to compile in visual studio");
printf("download llvm: http://releases.llvm.org/download.html");
// some_int is an unique_ptr to an int with a value of 1.
smart int *some_int = unique_ptr(int, );
printf("%p = %d\n", some_int, *some_int);
size_t init_body_len = ;
do_something(init_body_len);
// some_int is destroyed here
return ;
}
非常简单,代码严谨性不深究,大家看下示例的具体用法就可以了。
我都觉得简单得写注释都有点多余。
由于原项目文件挺多的,编译挺麻烦的。
就操刀简单修改了一下,
主要是将代码合为一个文件csptr_smart_ptr.h,附示例代码,干净便携。
对应项目地址:
https://github.com/cpuimage/libcsptr
只能说,有了它,你可以省下不少c内存管理心了。
当然会有很多人质疑说,会不会有大坑,
也许会有,也许没有,但是c智能指针的确可以有。
我比较相信事实,当然事实就是编译器提供了一个路子给你,
然而有些人确实可能会说,不相信编译器,
嗯,对的,我也不信。
但是,毫无疑问,大家虽然不信但是都在用。
嘴上那样说,身体还是很诚实的。
以上,权当抛砖引玉。
独乐乐不如一起玩乐。
若有其他相关问题或者需求也可以邮件联系俺探讨。
邮箱地址是:
gaozhihan@vip.qq.com
c语言智能指针 附完整示例代码的更多相关文章
- 看完48秒动画,让你不敢再登录HTTP网站(附完整示例代码)
在我的 单点登录SSO示例代码 一文中,强烈不建议部署HTTP的SSO服务站点. 在此写个基于网络包嗅探的HTTP会话劫持程序,给大家一个直观的危害性展示. 示例中,我在一台Mac上登录58同城,被另 ...
- 音频算法之小黄人变声 附完整C代码
前面提及到<大话音频变声原理 附简单示例代码>与<声音变调算法PitchShift(模拟汤姆猫) 附完整C++算法实现代码> 都稍微讲过变声的原理和具体实现. 大家都知道,算法 ...
- 基于傅里叶变换的音频重采样算法 (附完整c代码)
前面有提到音频采样算法: WebRTC 音频采样算法 附完整C++示例代码 简洁明了的插值音频重采样算法例子 (附完整C代码) 近段时间有不少朋友给我写过邮件,说了一些他们使用的情况和问题. 坦白讲, ...
- 基于RNN的音频降噪算法 (附完整C代码)
前几天无意间看到一个项目rnnoise. 项目地址: https://github.com/xiph/rnnoise 基于RNN的音频降噪算法. 采用的是 GRU/LSTM 模型. 阅读下训练代码,可 ...
- 音频降噪算法 附完整C代码
降噪是音频图像算法中的必不可少的. 目的肯定是让图片或语音 更加自然平滑,简而言之,美化. 图像算法和音频算法 都有其共通点. 图像是偏向 空间 处理,例如图片中的某个区域. 图像很多时候是以二维数据 ...
- mser 最大稳定极值区域(文字区域定位)算法 附完整C代码
mser 的全称:Maximally Stable Extremal Regions 第一次听说这个算法时,是来自当时部门的一个同事, 提及到他的项目用它来做文字区域的定位,对这个算法做了一些优化. ...
- 音频自动增益 与 静音检测 算法 附完整C代码
前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用于评估一定长度音频的音量强度, 而分析之后,很多类似的需求,肯定是做音频增益,提高音量诸如此类做法. ...
- 浮点数据有损压缩算法 附完整C代码
在几年前的时候在做修图APP算法的时候, 曾经一度想过对3D Lut 预设数据进行压缩, 主要用于提升用户体验. 关于3d lut算法开源的资源也挺多的,就不多做科普了. 有兴趣的朋友,可以去查阅下f ...
- 音频自动增益 与 静音检测 算法 附完整C代码【转】
转自:https://www.cnblogs.com/cpuimage/p/8908551.html 前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用 ...
随机推荐
- Javascript 中 true 和 false
"" == false // true "0" == false // true "" == "0" //false 以 ...
- 沉淀再出发:jetty的架构和本质
沉淀再出发:jetty的架构和本质 一.前言 我们在使用Tomcat的时候,总是会想到jetty,这两者的合理选用是和我们项目的类型和大小息息相关的,Tomcat属于比较重量级的容器,通过很多的容器层 ...
- 期初付年金(annuity-due)
含义:在 n 个时期,每个时期初付款1元. ——期初付年金的现值因子 ——期初付年金的积累值因子 关系: 二.期初付年金和期末付年金的关系
- 初始python(三)
1. 循环 if, while, forbreak : 结束整个循环continue :跳出当前这次循环,但不结束整个循环else :结束整个循环后才执行,不能与break合用,但可以与continu ...
- DB_NAME DB_UNIQUE_NAME 和 SID 的理解
1. DB_NAME 表示数据库名称,DB_NAME 会保持在数据文件头.控制文件.REDO文件里,所以更改DB_NAME不能仅仅修改spfile ,还需要用nid 来进行更改,并且更改后还需要手工做 ...
- python 网络编程 -- Tcp协议
Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可. 客户端 大多数连接都是可靠 ...
- win10 系统下获取系统版本号为6.2的问题
近期赶时髦升级了win10,用着挺爽.但是某天在测试一个bug时发现要对win10做特殊处理,于是直接调用了GetVersionEx,并取出版本号进行判断,但是发现得到的版本竟然是6.2.当时就被雷到 ...
- Hadoop学习之路(二十五)MapReduce的API使用(二)
学生成绩---增强版 数据信息 computer,huangxiaoming,85,86,41,75,93,42,85 computer,xuzheng,54,52,86,91,42 computer ...
- PHP扩展功能 ---- 页面静态化(OB缓冲)
一.入门三部曲 1.什么是页面静态化 百度百科介绍: 静态页面是网页的代码都在页面中,不需要执行asp,php,jsp,.net等程序生成客户端网页代码的网页,静态页面网址中一般不含"?&q ...
- 使用appassembler插件生成启动脚本
appassemblermaven插件可以自动生成跨平台的启动脚本,省去了手工写脚本的麻烦,而且还可以生成jsw的后台运行程序.插件官网:http://www.mojohaus.org/appasse ...