cleanup属性:当变量离开它的作用域时,设置的cleanup_function函数将被调用。

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 variablesit may not be applied to parameters or variables with static storage durationThe 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 will be run during the stack unwinding that happens during the processing of the exception. Note that the cleanupattribute 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.

#include <stdio.h>
#include <stdlib.h> #define local_type __attribute__ ((cleanup(my_free))) static void my_free(void* pmem)//the type of paramter must be a void pointer
{
printf("pmem=%p...\n", pmem);
printf("&pmem=%p...\n", &pmem);
void** ppmem = (void**) pmem;
printf("*ppmem=%p...\n", *ppmem);
free(*ppmem);
} #if 0
//warning: passing argument 1 of ‘my_free’ from incompatible pointer type
static void my_free(void** ppmem)
{
printf("ppmem=%p...\n", ppmem);
printf("*ppmem=%p...\n", *ppmem);
}
#endif int foo(void)
{
local_type int* p = (int*) malloc(sizeof(int));
printf("do something, p=%p\n", p); return ;
} int main(int argc, char** argv)
{ foo();
// when return, the memory block pointed by p is freed automatically
printf("11111111\n"); return ;
}

利用cleanup属性来实现智能指针:

 #include <stdlib.h>
#include <stdio.h> struct shared_ptr_s
{
// struct impl_t* inst;
int *use_cnt;
}; typedef struct shared_ptr_s shared_ptr_t; // unadorned type
#define shared_ptr struct shared_ptr_s __attribute__((cleanup(free_shared))) #define SHARED_PTR_GET_ADD_REF(sp_in, sp_name) ++(*sp_in.use_cnt); \
printf("add use_cnt = %d, sp_in=%p\n", *sp_in.use_cnt, sp_in); \
shared_ptr sp_name = sp_in; \
printf("&sp_name=%p, sp_name:%p\n", &sp_name, sp_name); void free_shared(struct shared_ptr_s* ptr)
{
printf("ptr:%p, usr_cnt:%p\n", ptr, ptr->use_cnt);
if(!ptr) return;
printf("del use_cnt = %d\n", *ptr->use_cnt - );
if( == --(*ptr->use_cnt)) {
//dtor(ptr->inst);
printf("freeing %p\n", (void *)ptr->use_cnt);
free(ptr->use_cnt);
}
//ptr->inst = 0;
ptr->use_cnt = ;
} void func(shared_ptr_t sp)
{
SHARED_PTR_GET_ADD_REF(sp, sp_loc);
printf("111111111\n");
return;
} int main(void)
{
shared_ptr_t sp = { // original type does not use __attribute__(cleanup)
//.inst = ctor(),
.use_cnt = malloc(sizeof(int))
};
printf("use_cnt content addr:%p, &use_cnt=%p, &sp=%p,sp=%p\n", sp.use_cnt, &sp.use_cnt, &sp,sp);
SHARED_PTR_GET_ADD_REF(sp, sp_loc); printf("222222222222\n");
func(sp_loc);
printf("333333333\n"); return ;
}

运行结果:

use_cnt content addr:0x9ee7008, &use_cnt=0xbfa11dac, &sp=0xbfa11dac,sp=0x9ee7008
add use_cnt = 1, sp_in=0x9ee7008
&sp_name=0xbfa11da8, sp_name:0x9ee7008
222222222222
add use_cnt = 2, sp_in=0x9ee7008
&sp_name=0xbfa11d74, sp_name:0x9ee7008
111111111
ptr:0xbfa11d74, usr_cnt:0x9ee7008
del use_cnt = 1
333333333
ptr:0xbfa11da8, usr_cnt:0x9ee7008
del use_cnt = 0
freeing 0x9ee7008

__attribute__系列之cleanup的更多相关文章

  1. __attribute__系列之介绍篇

    1.什么是__attribute__? __attribute__机制是GNU C的一大特色,它可以设置函数属性.变量属性和类型属性等.可以通过它们向编译器提供更多数据,帮助编译器执行优化等. 2._ ...

  2. __attribute__系列之aligned

    __attribute__的属性aligned,作用是为了设置字节对齐. aligned是对 变量和结构体进行 字节对齐的属性设置. 通过aligned属性设置(aligned(对齐字节数)),可以显 ...

  3. 如何在 Objective-C 的环境下实现 defer

    关注仓库,及时获得更新:https://github.com/draveness/iOS-Source-Code-Analyze Follow: https://github.com/Dravenes ...

  4. libextobjc 实现的 defer

    算法沉思录:分而治之(复用): 分而治之是指把大而复杂的问题分解成若干个简单的小问题,然后逐个解决.这种朴素的思想来源于人们生活与工作的经验,也完全适合于技术领域. 要崩溃的节奏: 要崩溃的节奏: V ...

  5. 黑魔法__attribute__((cleanup))

    原文地址:http://blog.sunnyxx.com/2014/09/15/objc-attribute-cleanup/ 编译器属性__attribute__用于向编译器描述特殊的标识.检查或优 ...

  6. [转]GCC系列: __attribute__((visibility("")))

    在 objc-api.h 里面有很多关于__attribute__ 的定义. 例如 #if !defined(OBJC_VISIBLE) # if TARGET_OS_WIN32 # if defin ...

  7. Objective-C 源码初探 __attribute__

    #import <Foundation/Foundation.h> //延迟执行,delayFunc函数即为延迟执行的函数 #define onExit\ __strong void (^ ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (11) -----第三章 查询之异步查询

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第三章 查询 前一章,我们展示了常见数据库场景的建模方式,本章将向你展示如何查询实体 ...

  9. Java多线程系列--“JUC线程池”03之 线程池原理(二)

    概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...

随机推荐

  1. HDOJ 2582 f(n)

    Discription This time I need you to calculate the f(n) . (3<=n<=1000000) f(n)= Gcd(3)+Gcd(4)+… ...

  2. 【分类讨论】Codeforces Round #395 (Div. 2) D. Timofey and rectangles

    D题: 题目思路:给你n个不想交的矩形并别边长为奇数(很有用)问你可以可以只用四种颜色给n个矩形染色使得相接触的 矩形的颜色不相同,我们首先考虑可不可能,我们分析下最多有几个矩形互相接触,两个时可以都 ...

  3. 【Floyd】【Dilworth定理】【最小路径覆盖】【匈牙利算法】bzoj1143 [CTSC2008]祭祀river

    Dilworth定理,将最长反链转化为最小链覆盖.//貌似还能把最长上升子序列转化为不上升子序列的个数? floyd传递闭包,将可以重叠的最小链覆盖转化成不可重叠的最小路径覆盖.(引用:这样其实就是相 ...

  4. 【状态压缩DP】BZOJ1087-[SCOI2005]互不侵犯King

    [题目大意] 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. [思路] 先预处理每一行可行的状态 ...

  5. Problem B: 调用函数,求1!+2!+3!+......+10!

    #include<stdio.h> double fact(int i); int main() { int i; ; ;i<=;i++) sum=sum+fact(i); prin ...

  6. ARP协议具体解释之ARP动态与静态条目的生命周期

    ARP协议详细解释之ARP动态与静态条目的生命周期 ARP动态条目的生命周期 动态条目随时间推移自己主动加入和删除. q  每一个动态ARP缓存条目默认的生命周期是两分钟.当超过两分钟,该条目会被删掉 ...

  7. k8s debug记录之kubelet user.slice container monitor failure

    在kubernetes中,如果使用其自带的单机启动脚本./hack/local-up-cluster.sh来启动一个本地集群的话,会在kubelet的日志中观察到类似以下内容的日志: Failed t ...

  8. docker 安装 gogs(go git server) 及问题解决

    docker安装gogs 参考官方说明 gogs mysql 支持 运行一个mysql image docker run --name gogs-mysql -e MYSQL_ROOT_PASSWOR ...

  9. Spark(一)-- Standalone HA的部署

    首先交代一下集群的规模和配置 集群有六台机器,均是VM虚拟机,每台256M的内存(原谅楼主物理机硬件不太给力) 主机名分别是cloud1~cloud6 每台机器上都装有jdk6,和hadoop-2.2 ...

  10. 数据挖掘算法之关联规则挖掘(二)FPGrowth算法

    之前介绍的apriori算法中因为存在许多的缺陷,例如进行大量的全表扫描和计算量巨大的自然连接,所以现在几乎已经不再使用 在mahout的算法库中使用的是PFP算法,该算法是FPGrowth算法的分布 ...