__attribute__中的constructor和destructor--如何让程序退出时调用指定函数

news2024/9/24 23:24:54

背景

假设你在开发一个基础组件x,然后你设计了一个x_init接口用来初始化这个组件,相应地你设计了一个x_deinit来去初始化。这样其它模块要用到这个组件时,先调一下x_init, 用完了再调一下x_deinit。init和deinit这是一对很常见的接口,这种用法也很常见。
那么问题来了,假设同一进程中使用你这个的组件不止一个,比如A,B两个独立模块都要使用,甚至A和B都不知道对方的存在,它们最开始都要调用x_init, 这个只要在内部实现做好保护,x_init多次调用,并发调用也能hold得住 。但是对于x_deinit该怎么调用,该谁去调用呢?
假设A先退出,然后调用x_deinit, 这时,如果B还在使用就有可能出现问题。如果A不调deinit, 到B退出时,B也不知道还有没有人在使用x, 所以B也没有调deinit, 最后导致的结果可能就是资源泄漏。
如果是C++, 这个问题比较好解决,只需要定义一个全局变量,然后在析构函数里边调用x_deinit即可。
如果是C语言怎么办?我们需要的是在程序退出时,能够自动调用x_deinit.

__attribute__中的constructor和destructor

__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。__attribute__前后都有两个下划线,并且后面会紧跟一对原括弧,括弧里面是相应的__attribute__参数

__attribute__语法格式为:attribute ( ( attribute-list ) )

若函数被设定为constructor属性,则该函数会在main()函数执行之前被自动的执行。类似的,若函数被设定为destructor属性,则该函数会在main()函数执行之后或者exit()被调用后被自动的执行。例如下面的程序:

#include <stdio.h>
#include <stdlib.h>
static int * g_count = NULL;
__attribute__((constructor)) void x_init()
{
    printf("Constructor is called.\n");
    g_count = (int *)malloc(sizeof(int));
    if (g_count == NULL)
    {
    fprintf(stderr, "Failed to malloc memory.\n");
    }
}
__attribute__((destructor)) void x_deinit()
{
    printf("destructor is called.\n");
    if (g_count)
    free(g_count);
}
int main()
{
    return 0;
}

程序执行结果如下:

在这里插入图片描述
利用destructor这个属性,我们就能做到让程序退出时自动调用deinit函数,完美解决可能的资源泄漏问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1152061.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NB-IOT的粮库挡粮门异动监测装置

一种基于NBIOT的粮库挡粮门异动监测装置,包括若干个NBIOT开门监测装置,物联网后台管理系统,NBIOT低功耗广域网络和用户访问终端;各个NBIOT开门监测装置通过NBIOT低功耗广域网络与物联网后台管理系统连接,物联网后台管理系统与用户访问终端连接.NBIOT开门监测装置能够对粮库挡粮…

网络新闻发稿为何经久不衰?

有的老板可能看不到新闻营销的直接回报&#xff0c;一直不乐意在此方面投入&#xff0c;但是却看到竞争对手一直在搞新闻营销&#xff0c;也就安排个PR做做新闻公关。小马识途营销顾问观察&#xff0c;自互联网诞生以来&#xff0c;新闻营销一直是网络营销工作中的一个重点。 如…

JS中的元编程

ES6&#xff08;ECMAScript 2015&#xff09;新增了对 Reflect 和 Proxy 对象的支持&#xff0c;使得我们能够便捷地进行元编程。让我们通过示例来学习它们的用法。 1、什么是元编程 元编程 无异于 编程中的魔法&#xff01;如果编写一个“能够读取、修改、分析、甚至生成新程…

提高小程序SEO 排名,9招优化技巧!

在当今移动互联网时代&#xff0c;小程序已经成为企业必不可少的一种营销手段&#xff0c;而如何让用户能够更容易地找到自己的小程序&#xff0c;就需要进行SEO优化&#xff0c;提升小程序的排名&#xff0c;本文将 为大家介绍9个小程序SEO优化技巧&#xff0c;帮助您的小程序…

黑客技术(网络安全)——如何高效学习

前言 前几天发布了一篇 网络安全&#xff08;黑客&#xff09;自学 没想到收到了许多人的私信想要学习网安黑客技术&#xff01;却不知道从哪里开始学起&#xff01;怎么学 今天给大家分享一下&#xff0c;很多人上来就说想学习黑客&#xff0c;但是连方向都没搞清楚就开始学习…

OPENCV 闭运算实验示例代码morphologyEx()函数

void CrelaxMyFriendDlg::OnBnClickedOk() {hdc this->GetDC()->GetSafeHdc();// TODO: 在此添加控件通知处理程序代码string imAddr "c:/Users/actorsun/Pictures/";string imAddr1 imAddr"rice.png";Mat relax, positive;relax imread(imAddr1…

Linux的基础常用指令

常用指令汇及其功能 ls 列出当前文件夹有哪些文件 ls -a显示所有文件&#xff0c;包含隐藏的文件和文件夹pwd显示当前是在哪个文件夹下mkdirmkdir名字→创建文件夹cdcd名字→进入某个指定文件夹cd .. 退回上层文件夹(cd后有空格) Tab键自动补全&#xff1a;文件或文件名太长&a…

信息系统项目管理师教程 第四版【第8章-项目整合管理-思维导图】

信息系统项目管理师教程 第四版【第8章-项目整合管理-思维导图】 课本里章节里所有蓝色字体的思维导图

【设计模式】第11节:结构型模式之“装饰器模式”

一、简介 装饰器模式主要解决继承关系过于复杂的问题&#xff0c;通过组合来替代继承。它主要的作用是给原始类添加增强功能。这也是判断是否该用装饰器模式的一个重要的依据。除此之外&#xff0c;装饰器模式还有一个特点&#xff0c;那就是可以对原始类嵌套使用多个装饰器。…

LeetCode169——多数元素(众数)

LeetCode169——多数元素&#xff08;众数&#xff09; 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 Result01&#xff08…

顺序表的模拟

前言&#xff1a; 数据结构无论是以后就业还是考研&#xff0c;对于计算机方向的同学来说都是必修的一门课&#xff0c;所以&#xff0c;深入理解各种数据结构是一名合格程序员的基本素养。这里我就先带大家了解最简单的数据结构--顺序表吧。 1.什么是顺序表 顺序表是一种线性…

菜单管理中icon图标回显

<el-table-column prop"icon" label"图标" show-overflow-tooltip algin"center"><template v-slot"{ row }"><el-icon :class"row.icon"></el-icon></template></el-table-column>

Xilinx 7 系列 1.8V LVDS 和 2.5V LVDS 信号之间的 LVDS 兼容性

如果通过LVDS进行接口&#xff0c;可以按照以程图中的步骤操作&#xff0c;以确保满足正确使用LVDS的所有要求。 40191 - 7 系列 - 1.8V LVDS 和 2.5V LVDS 信号之间的 LVDS 兼容性 与LVDS兼容驱动器和接收器连接时&#xff0c;7系列LVDS和LVDS_25输入和输出应该不存在兼容性问…

基于若依的ruoyi-nbcio流程管理系统增加仿钉钉流程设计(一)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 仿钉钉的开源项目网上也不少&#xff0c;而且很多功能已经也比较完善了&#xff0c;但大部分都不是MIT协议…

Ubuntu系统HUSTOJ 用 vim 修改php.ini 重启PHP服务

cd / sudo find -name php.ini 输出&#xff1a; ./etc/php/7.4/cli/php.ini ./etc/php/7.4/fpm/php.ini sudo vim /etc/php/7.4/cli/php.ini sudo vim /etc/php/7.4/fpm/php.ini 知识准备&#xff1a; vim的搜索与替换 在正常模式下键入 / &#xff0c;即可进入搜索模式…

计数排序(秒懂版)

public class CountingSort {int[] sort() {int N 10000;int M 100;//假设A中最大值为100int A[] new int[N];//1~k,原数组int B[] new int[N];//1~k,Stores incompletely sorted numbersint C[] new int[M 1];//0~n,辅助排序数组for (int i 0; i < M; i) {C[i] 0;}…

案例分析真题-信息安全

案例分析真题-信息安全 2009年真题 【问题1】 【问题2】 【问题3】 2010年真题 【问题1】 【问题2】 【问题3】 2011 年真题 【问题1】 【问题2】 【问题3】 骚戴理解&#xff1a;这个破题目完全考的知识储备&#xff0c;不知道的连手都动不了&#xff0c;没法分析 2013年真题…

Linux基础指令[下]

文章目录 0.英语单词3.Linux的重要指令[下]1. 输入/输出重定向1.1echo和输出重定向1.2cat和输入重定向1.3Linux文件理念 2.长文本逐行查看2.1more的介绍2.2建议使用less2.3more/less的选项 3.head&&tail显示头尾对head&&tail的认识练习head和tail 4.时间指令4.…

vue2+ant-design-vue a-select组件二次封装(支持单选/多选添加全选/分页(多选跨页选中)/自定义label)

一、效果图 二、参数配置 1、代码示例 <t-antd-selectv-model"selectVlaue":optionSource"stepList"change"selectChange" />2、配置参数&#xff08;Attributes&#xff09;继承 a-select Attributes 参数说明类型默认值v-model绑定值…

【陈老板赠书活动 - 16期】- 【快捷学习Spring】

陈老老老板&#x1f9b8; &#x1f468;‍&#x1f4bb;本文专栏&#xff1a;赠书活动专栏&#xff08;为大家争取的福利&#xff0c;免费送书&#xff09; &#x1f468;‍&#x1f4bb;本文简述&#xff1a;生活就像海洋,只有意志坚强的人,才能到达彼岸。 &#x1f468;‍&am…