专栏首页算法+c语言智能指针 附完整示例代码
原创

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, { 0 }, 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, 1);
    printf("%p = %d\n", some_int, *some_int);
    size_t init_body_len = 4096;
    do_something(init_body_len);
    // some_int is destroyed here
    return 0;
}

非常简单,代码严谨性不深究,大家看下示例的具体用法就可以了。

我都觉得简单得写注释都有点多余。

由于原项目文件挺多的,编译挺麻烦的。

就操刀简单修改了一下,

主要是将代码合为一个文件csptr_smart_ptr.h,附示例代码,干净便携。

对应项目地址:

https://github.com/cpuimage/libcsptr

只能说,有了它,你可以省下不少c内存管理心了。

当然会有很多人质疑说,会不会有大坑,

也许会有,也许没有,但是c智能指针的确可以有。

我比较相信事实,当然事实就是编译器提供了一个路子给你,

然而有些人确实可能会说,不相信编译器,

嗯,对的,我也不信。

但是,毫无疑问,大家虽然不信但是都在用。

嘴上那样说,身体还是很诚实的。

以上,权当抛砖引玉。

独乐乐不如一起玩乐。

若有其他相关问题或者需求也可以邮件联系俺探讨。

邮箱地址是:  gaozhihan@vip.qq.com

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 音频增益响度分析 ReplayGain 附完整C代码示例

    人们所熟知的图像方面的3A算法有: AF自动对焦(Automatic Focus) 自动对焦即调节摄像头焦距自动得到清晰的图像的过程 AE自动曝光(Automa...

    cpuimage
  • 快速堆栈模糊算法

    上一篇快速高斯模糊的原作者也有另一个比较快速的模糊算法Stack Blur,字面意思为堆栈模糊。 源地址为:http://incubator.quasimond...

    cpuimage
  • 学习图像算法阶段性总结 (附一键修图Demo) 2016.04.19更新demo

    今天特别感慨,自己从决定研究图像处理,势必要做出一键修图算法。 经历了,三个多月的书籍积累,三个多月的算法调整以及优化。 人是一种奇怪的动物,当你做不到的时候,...

    cpuimage
  • –[New]Vue项目使用vw实现移动端适配教程

    大象无痕
  • 数据库连接池到底应该设多大?这篇文章可能会颠覆你的认知

    数据库连接池大小往往是一个很容易被大家所忽略的参数,通常这个参数也和公司或者组内文化有关系,以前在美团的时候基本所有的项目连接池大小都设置20, 当时也没有考虑...

    用户5397975
  • ​eggjs实战

    swagger会扫描配置的API文档格式自动生成一份json数据,而swagger官方也提供了ui来做通常的展示,当然也支持自定义ui的。不过对后端开发者来说,...

    一粒小麦
  • 教程 | 从硬件配置、软件安装到基准测试,1700美元深度学习机器构建指南

    选自Medium 作者:Slav 机器之心编译 参与:Quantum Cheese、Lj Linjing、蒋思源 在用了十年的 MacBook Airs 和云...

    机器之心
  • 网站修改.htaccess文件实现301重定向方法整理汇总

    网站进行301重定向对广大站长来说并不陌生,处于SEO、PR值传递等都会对网站设置301跳转,通常我们做301重定向都是修改网站根目录下.htaccess文件,...

    主机侦探
  • 类似 深度学习自动特征 的 强化学习自动辅助任务学表征

    强化学习的自动任务:表示学习是和适应环境的任务相关的;这篇论文给出了任务相关的表示学习的理论证明。

    用户1908973
  • 这个MySQL优化原理剖析,比照X光还清楚

    | 作者 沈启超,19年硕士毕业于东南大学,目前在腾讯CSIG企业产品部担任后台开发,同时也参与公司内部存储开源组件MySync的开发。 ---- 前言:M...

    腾讯云数据库 TencentDB

扫码关注云+社区

领取腾讯云代金券