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代码示例> 主要用 ...
随机推荐
- iOS设计模式 - 外观
iOS设计模式 - 外观 原理图 说明 1. 当客服端需要使用一个复杂的子系统(子系统之间关系错综复杂),但又不想和他们扯上关系时,我们需要单独的写出一个类来与子系统交互,隔离客户端与子系统之间的联系 ...
- Google官方教程之Selling In-app Products
1.原文链接[需FQ]:http://developer.android.com/training/in-app-billing/index.html 2.平时对于英文文档都是大概读一下,现在翻译文章 ...
- 企业级Nginx基于虚拟主机别名的设置
生活中访问www.baidu.com和baidu.com是一个效果,同理也可以用rewrite 301跳转的思路(多发了一次请求过去)配置nginx.conf文件或者include里面的引用的文件,道 ...
- January 12 2017 Week 2 Thursday
Although it rains, throw not away your watering pot. 纵然天下雨,休把水壶丢. Don't throw away your watering pot ...
- BZOJ3174:[TJOI2013]拯救小矮人(DP)
Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人, ...
- js事件的机制
1.html事件处理程序 <button id="btn1" onclick="alert(1);">按钮1</button> 2.do ...
- linq的左连接右连接内连接用法
1.左连接: var LeftJoin = from e in ListOfEmployees join d in ListOfDepartment on e.DeptID equals d.ID i ...
- multimap详讲
multimap和map的区别: 首先认识一下multimap和map的区别: 1> multimap不提供operator[ ]运算符.因为这个运算符的语义在同一个键可以保存多个 ...
- urlparse 用法
ifrom urllib2 import urlparse ‘’ captcha_id = urlparse.parse_qs(urlparse.urlparse(link).query, True) ...
- jFinal 2.2入门学习之一:搭建框架输出helloword
官方推荐用Eclipse IDE for Java EE Developers 做为开发环境 1.创建 Dynamic Web Project 2.修改 Default Output Folder,推 ...