是的,你没有看错,

不是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语言智能指针 附完整示例代码的更多相关文章

  1. 看完48秒动画,让你不敢再登录HTTP网站(附完整示例代码)

    在我的 单点登录SSO示例代码 一文中,强烈不建议部署HTTP的SSO服务站点. 在此写个基于网络包嗅探的HTTP会话劫持程序,给大家一个直观的危害性展示. 示例中,我在一台Mac上登录58同城,被另 ...

  2. 音频算法之小黄人变声 附完整C代码

    前面提及到<大话音频变声原理 附简单示例代码>与<声音变调算法PitchShift(模拟汤姆猫) 附完整C++算法实现代码> 都稍微讲过变声的原理和具体实现. 大家都知道,算法 ...

  3. 基于傅里叶变换的音频重采样算法 (附完整c代码)

    前面有提到音频采样算法: WebRTC 音频采样算法 附完整C++示例代码 简洁明了的插值音频重采样算法例子 (附完整C代码) 近段时间有不少朋友给我写过邮件,说了一些他们使用的情况和问题. 坦白讲, ...

  4. 基于RNN的音频降噪算法 (附完整C代码)

    前几天无意间看到一个项目rnnoise. 项目地址: https://github.com/xiph/rnnoise 基于RNN的音频降噪算法. 采用的是 GRU/LSTM 模型. 阅读下训练代码,可 ...

  5. 音频降噪算法 附完整C代码

    降噪是音频图像算法中的必不可少的. 目的肯定是让图片或语音 更加自然平滑,简而言之,美化. 图像算法和音频算法 都有其共通点. 图像是偏向 空间 处理,例如图片中的某个区域. 图像很多时候是以二维数据 ...

  6. mser 最大稳定极值区域(文字区域定位)算法 附完整C代码

    mser 的全称:Maximally Stable Extremal Regions 第一次听说这个算法时,是来自当时部门的一个同事, 提及到他的项目用它来做文字区域的定位,对这个算法做了一些优化. ...

  7. 音频自动增益 与 静音检测 算法 附完整C代码

    前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用于评估一定长度音频的音量强度, 而分析之后,很多类似的需求,肯定是做音频增益,提高音量诸如此类做法. ...

  8. 浮点数据有损压缩算法 附完整C代码

    在几年前的时候在做修图APP算法的时候, 曾经一度想过对3D Lut 预设数据进行压缩, 主要用于提升用户体验. 关于3d lut算法开源的资源也挺多的,就不多做科普了. 有兴趣的朋友,可以去查阅下f ...

  9. 音频自动增益 与 静音检测 算法 附完整C代码【转】

    转自:https://www.cnblogs.com/cpuimage/p/8908551.html 前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用 ...

随机推荐

  1. [翻译] PPDragDropBadgeView

    PPDragDropBadgeView https://github.com/smallmuou/PPDragDropBadgeView PPDragDropBadgeView is a badge ...

  2. Hibernate 一次查询分多次返回 避免内存溢出

    public void grpcGpioDevice(StreamObserver<NI_GetAllDeviceListResponse> responseObserver, Map&l ...

  3. 组合数计算-java

    排列组合是计算应用经常使用的算法,通常使用递归的方式计算,但是由于n!的过于大,暴力计算很不明智.一般使用以下两种方式计算. 一,递归的思想:假设m中取n个数计算排列组合数,表示为comb(m,n). ...

  4. codeforces 156D Clues(prufer序列)

    codeforces 156D Clues 题意 给定一个无向图,不保证联通.求添加最少的边使它联通的方案数. 题解 根据prufer序列,带标号无根树的方案数是\(n^{n-2}\) 依这个思想构建 ...

  5. Java 多态(接口)

    有两种意义的多态,一是操作名称的多态,即有多个操作具有相同的名字,但这些操作所接收的消息类型必须不同(方法重载).另一种多态是和继承有关的多态,是指同一个操作被不同类型对象调用时可能产生不同的行为(方 ...

  6. win环境下使用sqlmap写shell + MYSQL提权(默认就是system权限)

    今天在来一个mysql提权 (也可以说是默认system权限提的) 在被黑站点找到一个站   先教拿shell是有注入漏洞的 有可能是root权限的注入点 可以确定是有注入漏洞的 也得到了 物理路径 ...

  7. C语言程序员必读的5本书

    本文由 伯乐在线 - programmer_lin 翻译自 fromdev.欢迎加入技术翻译小组.转载请参见文章末尾处的要求. 你正计划着通过看书来学习C语言吗?“书籍是人类最忠诚的朋友“.海明威一定 ...

  8. 【[HAOI2015]树上染色】

    这道题真是非常神仙 第一眼看到题面肯定能想到状态是\(dp[i][j]\)表示\(i\)这棵子树里染了\(j\)个黑点的最大值 最大值? 什么最大值,之后就会发现这个样子完全没有办法转移 所以我们考虑 ...

  9. [Python 多线程] Lock、阻塞锁、非阻塞锁 (八)

    线程同步技术: 解决多个线程争抢同一个资源的情况,线程协作工作.一份数据同一时刻只能有一个线程处理. 解决线程同步的几种方法: Lock.RLock.Condition.Barrier.semapho ...

  10. linq中当生成asp.net实体模式时

    linq中当生成asp.net实体模式时 注意: 选中 工具->库程序包管理器->管理解决方案的nuget程序包  选中下面的进行下载.