__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 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的更多相关文章
- __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之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...
随机推荐
- 【树上莫队】bzoj3757 苹果树
学习这位神犇的:http://blog.csdn.net/jiangyuze831/article/details/41476865 注意: ①排序时第一关键字是左端点所在块编号(块状树),第二关键字 ...
- JavaSE目录
常识,环境变量,注释 标示符,常量,进制转换,类型转换,位运算符,语句 数组,函数 面向对象 多线程 String 包装类 集合 其他对象 IO流,IO流--FileReader&&F ...
- 使用GIT时排除NuGet的packages文件夹
这段时间一直在用GIT做本地自己写的程序的源码管理工具,在使用的过程中发现了一个问题:Git往往会把NuGet的packages文件夹作为项目的一部分给添加进来了.网上搜了一下,原因是GIT只是和文件 ...
- CASJAVA一些理解
如果不用锁机制如何实现共享数据访问.(不要用锁,不要 用sychronized 块或者方法,也不要直接使用 jdk 提供的线程安全的数据结构,需要自己实现一个类来保证多个线程同时读写这个类中的共享 ...
- 【tomcat】FileNotFoundException: C:\Program Files\Java\apache-tomcat-8.5.11-geneshop3\webapps\ROOT\index.html (拒绝访问。)
新装系统后,tomcat启动起来 提示如下错误: Caused by: java.io.FileNotFoundException: C:\Program Files\Java\apache-tomc ...
- python3读取html文件
# htmlf=open('E:\\test2.html','r',encoding="utf-8") # htmlcont=htmlf.read() # print(type(h ...
- python - ImportError: No module named pywintypes
must restart the python shell to avoid this issue after pywin32 installed
- TortoiseSVN 使用简介
什么是SVN(subversion)? 有一个简单但不十分精确的比喻:SVN = 版本控制 + 备份服务. 简单的说就是,你可以把SVN看做一个备份服务器,但是更好的是,他可以帮助记住每一次上传的版本 ...
- GLSL使用FBO实现MRT(Multiple Render Targets)绘制到多张纹理 【转】
项目的程序里设计需要将某一帧渲染出来的画面拆成三通道单色图像存到三张纹理里面.要绘制到纹理里,自然就想到FBO了.但是一次要输出多张纹理,这个还没接触过.一阵网上搜索过后,终于了解到了MRT(多重渲染 ...
- Solr6.6.0 用 SimplePostTool索引文件的启示
本文主要是介绍通过SimplePostTool工具索引文件的结果进行确认,针对不同的文件,索引的结果不同. 1.创建core 首先启动solr,建立名称为data的core,SimplePostToo ...