__attribute__系列之cleanup
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 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 will be 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.
#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的更多相关文章
- __attribute__系列之介绍篇
1.什么是__attribute__? __attribute__机制是GNU C的一大特色,它可以设置函数属性.变量属性和类型属性等.可以通过它们向编译器提供更多数据,帮助编译器执行优化等. 2._ ...
- __attribute__系列之aligned
__attribute__的属性aligned,作用是为了设置字节对齐. aligned是对 变量和结构体进行 字节对齐的属性设置. 通过aligned属性设置(aligned(对齐字节数)),可以显 ...
- 如何在 Objective-C 的环境下实现 defer
关注仓库,及时获得更新:https://github.com/draveness/iOS-Source-Code-Analyze Follow: https://github.com/Dravenes ...
- libextobjc 实现的 defer
算法沉思录:分而治之(复用): 分而治之是指把大而复杂的问题分解成若干个简单的小问题,然后逐个解决.这种朴素的思想来源于人们生活与工作的经验,也完全适合于技术领域. 要崩溃的节奏: 要崩溃的节奏: V ...
- 黑魔法__attribute__((cleanup))
原文地址:http://blog.sunnyxx.com/2014/09/15/objc-attribute-cleanup/ 编译器属性__attribute__用于向编译器描述特殊的标识.检查或优 ...
- [转]GCC系列: __attribute__((visibility("")))
在 objc-api.h 里面有很多关于__attribute__ 的定义. 例如 #if !defined(OBJC_VISIBLE) # if TARGET_OS_WIN32 # if defin ...
- Objective-C 源码初探 __attribute__
#import <Foundation/Foundation.h> //延迟执行,delayFunc函数即为延迟执行的函数 #define onExit\ __strong void (^ ...
- 《Entity Framework 6 Recipes》中文翻译系列 (11) -----第三章 查询之异步查询
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第三章 查询 前一章,我们展示了常见数据库场景的建模方式,本章将向你展示如何查询实体 ...
- Java多线程系列--“JUC线程池”03之 线程池原理(二)
概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...
随机推荐
- [BZOJ 1794] Linear Garden
Link: BZOJ 1794 传送门 Solution: IOI2008官方题解:传送门 要求序号,其实就是算字典序比其小的序列个数 从而使用数位$dp$的思想来解题,关键在于维护序列要$balan ...
- es 数据 导出 到 MySQL
暂时没有找到直接 导出到 mysql 数据库的工具 或者项目 目前实现思路: 使用 elasticdump 工具 实现 从 es 数据 导出到 json 文件 ,然后 使用 脚本程序 操作 改 js ...
- 让XCode的Stack Trace信息可读
程序报错信息如下:
- dwz中弹出的窗口页面如何获取前页面(点击按钮的页面)的元素???
在页面A.jsp中点击一个按钮,使用$.pdialog.open()方法弹出b.jsp页面(对话框窗口),我要在b.jsp中选中值然后关闭窗口(b.jsp)返回值给A.jsp~ =========== ...
- ubi层次
转:http://www.360doc.com/content/11/0518/13/496343_117643185.shtml UBI是什么? 它是一种flash管理方式 flash是一系列连续的 ...
- [转] C++ try catch() throw 异常处理
原文地址 其它很多程序员一样,本书的主人公阿愚也是在初学C++时,在C++的sample代码中与异常处理的编程方法初次邂逅的,如下: // Normal program statements . ...
- Eclipse新建java类的时候,自动创建注释
为形成个人的java代码风格,我们在项目组中进行开发的时候,可以对自己的代码进行一些格式上面的设置,具体如下: 方法一:Eclipse中设置在创建新类时自动生成注释 windows–>prefe ...
- [Android Traffic] 看无线电波如何影响网络操作]
转载自: http://blog.csdn.net/kesenhoo/article/details/7391031 Optimizing Downloads for Efficient Networ ...
- JS使用cookie实现DIV提示框只显示一次的方法
本文实例讲述了JS使用cookie实现DIV提示框只显示一次的方法.分享给大家供大家参考,具体如下: 这里运用JavaScript的cookie技术,控制网页上的提示DIV只显示一次,也就是当用户是第 ...
- Hive中日期函数总结
--Hive中日期函数总结: --1.时间戳函数 --日期转时间戳:从1970-01-01 00:00:00 UTC到指定时间的秒数 select unix_timestamp(); --获得当前时区 ...