C/C++知识点之c语言智能指针 附完整示例代码
小标 2018-09-18 来源 : 阅读 946 评论 0

摘要:本文主要向大家介绍了C/C++知识点之c语言智能指针 附完整示例代码,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了C/C++知识点之c语言智能指针 附完整示例代码,通过具体的内容向大家展示,希望对大家学习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 
#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: //cpuimage.cnblogs.com/\n");
    printf("tips: u can use llvm to compile in visual studio");
    printf("download llvm: //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/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程