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代码示例> 主要用 ...
随机推荐
- Python实例---基于页面的后台管理[简单版]
后台管理菜单 + 母板[css/content/js] 向后台提交数据[2种]: 1. 模态对话框(数据少操作,且Js复杂): form表单 :优点:简单,前端提交后后台处 ...
- 沉淀再出发:IoC和AOP的本质
沉淀再出发:IoC和AOP的本质 一.前言 关于IoC和AOP这两个概念,如果我们没有深入的理解可以说是根本就不理解Spring这个架构的,同样的由Spring演变出来的Spring Boot和Spr ...
- Android sdk manager 更新 5.0 太难了,终于解决
由于众所周知的原因,必须在hosts中增加一些网址对应,才可以更新 203.208.46.146 www.google.com 203.208.46.1 plus.google.com 203.208 ...
- TCP握手建立与释放连接
网络层次模型 TCP/UDP区别 UDP,在传送数据前不需要先建立连接,远地的主机在收到UDP报文后也不需要给出任何确认.虽然UDP不提供可靠交付,但是正是因为这样,省去和很多的开销,使得它的速度比较 ...
- 【[JXOI2017]加法】
江西竟然还有省选,而且还是可怜题,实在是有点可怕 这道题还是比较清真的,大概是最简单的可怜题? 首先看到最大值最小,就很容易想到了二分答案 对于一个二分出来的答案\(mid\),去把原数列扫一遍就可以 ...
- Python中的类(一)
Python中的类(一) 一. 应用场景 如果多个函数中有一些相同的参数时,转换成面向对象. 二. 如何创建类 类是用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法 ...
- 如何使用Loadrunner12录制WebSocket脚本
简单说一下,关于Loadrunner12对WebSocket的支持可以参照以下文档: http://community.hpe.com/t5/LoadRunner-and-Performance/As ...
- POJ 3261 Milk Patterns 【后缀数组 最长可重叠子串】
题目题目:http://poj.org/problem?id=3261 Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Subm ...
- 【Webpack】学习随笔
参考链接:http://www.runoob.com/w3cnote/webpack-tutorial.html Webpack 是一个前端资源加载/打包工具. Webpack 可以将多种静态资源 j ...
- 《metasploit渗透测试魔鬼训练营》学习笔记第四章—web应用渗透
继续来学习metasploit...记好笔记是很重要的,下面开始正文: 二.WEB应用渗透技术 1.WEB应用渗透基础知识 先介绍WEB应用攻击的主要类型(大致介绍,具体请自行查 ...