__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之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...
随机推荐
- luogu P2024 食物链
题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的一种,但是我 ...
- 洛谷 P4173 残缺的字符串
(不知道xjb KMP可不可以做的说) (假设下标都以0开头) 对于有一定偏移量的序列的 对应位置 匹配或者数值计算的题,这里是有一种套路的,就是把其中一个序列翻转过来,然后卷积一下,所得到的新序列C ...
- 前端基础-JavaScript的基本概述和语法
1.JavaScript概述 2.JavaScript引入方式 3.JavaScript语言规范 4.JavaScript语言基础 5.JavaScript数据类型 6.JavaScript运算符 7 ...
- 1.7(学习笔记)过滤器(Fliter)
一.过滤器(Fliter)简介 过滤器是位于客户端与服务器之间的滤网,在访问资源时会经过一系列的过滤器, 满足条件则放行,不满足条件的将其拦截. 过滤器可以看做是一个特殊的Servlet,设置了过滤器 ...
- Bean实例化(三种方法)
(一)构造器实例化Bean 1. Bean1.java package com.inspur.ioc; public class Bean1 { } 2.Beans1.xml <?xml ver ...
- windbg学习—-.ecxr
.ecxr 命令定位当前异常的上下文信息,并显示指定记录中的重要寄存器 0:000> .ecxr eax=10000000 ebx=7ffd9000 ecx=77386500 edx=002 ...
- 修改input type=file 标签默认样式的简单方法
<html><head><title></title></head><body><form id="upload ...
- Go语言的9大优势和3大缺点, GO语言最初的定位就是互联网时代的C语言, 我为什么放弃Go语言
Go语言的9大优势和3大缺点 转用一门新语言通常是一项大决策,尤其是当你的团队成员中只有一个使用过它时.今年 Stream 团队的主要编程语言从 Python 转向了 Go.本文解释了其背后的九大原因 ...
- ubuntu中apt使用以及centos中yum的使用
centos和ubuntu是两大linux主流阵营 在centos中下载安装软件的方式 rpm rpm命令是RPM软件包的管理工具.rpm原本是Red Hat Linux发行版专门用来管理Linux各 ...
- javascript快速入门27--XSLT基础
XSL 与 XSLT XSL 指扩展样式表语言(EXtensible Stylesheet Language).它主要被用来对XML文档进行格式化,与CSS不同,XSL不仅仅是样式表语言XSL主要包括 ...