atexit函数的执行顺序_atexit()函数注册机制及调用次序 | 术与道的分享

atexit()是C/C++标准库中的一个函数,用于在程序正常结束时按注册顺序逆序执行指定的清理函数。这篇博客详细介绍了atexit的函数原型、作用及调用次序,并通过示例展示了其功能。同时,文中提到虽然ISO C规定最多可注册32个函数,但在实际应用中,注册数量可能受到堆内存限制,而非固定限制。
摘要由CSDN通过智能技术生成

atexit()的原型

atexit的函数原型如下:可以看出它是一个函数指针,里面存放的是函数的地址,当调用此函数时无须传递任何参数,该参数也不能有返回值。

int atexit( void ( __cdecl *func )( void ) );

1

intatexit(void(__cdecl *func)(void));

atexit()的作用

在标准库中有这样的描述:

The atexit function is passed the address of a function (func) to be called when the program terminates normally. Successive calls to atexit create a register of functions that are executed in LIFO (last-in-first-out) order. The functions passed to atexit cannot take parameters. atexit and _onexit use the heap to hold the register of functions. Thus, the number of functions that can be registered is limited only by heap memory.

1

Theatexitfunctionispassedtheaddressofafunction(func)tobecalledwhentheprogramterminatesnormally.SuccessivecallstoatexitcreatearegisteroffunctionsthatareexecutedinLIFO(last-in-first-out)order.Thefunctionspassedtoatexitcannottakeparameters.atexitand_onexitusetheheaptoholdtheregisteroffunctions.Thus,thenumberoffunctionsthatcanberegisteredislimitedonlybyheapmemory.

翻译过来的意思就是:当程序正常终止时,atexit函数传递要调用的函数(func)的地址。 对atexit的连续调用创建一个在LIFO(先进先出)命令中执行的功能寄存器。 传递给atexit的函数不能有参数。 atexit和_onexit使用堆来保存函数的寄存器。 因此,可以注册的功能数量仅受堆存储器限制。

atexit()的调用次序

#include

#include

void func1(void)

{

printf("func1()\n");

}

void func2(void)

{

printf("func2()\n");

}

void func3(void)

{

printf("func3()\n");

}

int main()

{

atexit(func1);

atexit(func2);

atexit(func3);

printf("main\n");

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#include

#include

voidfunc1(void)

{

printf("func1()\n");

}

voidfunc2(void)

{

printf("func2()\n");

}

voidfunc3(void)

{

printf("func3()\n");

}

intmain()

{

atexit(func1);

atexit(func2);

atexit(func3);

printf("main\n");

return0;

}

你会发现,首先调用的是main,说明atexit是在进程退出的时候,调用曾经注册过的函数,即atexit在退出前会进行注册,退出时进行回调。

atexit可以注册多个函数,调用多个函数时,它的调用顺序并不是调用次序,而是压栈次序,即先进后出。如果一个函数被多次登记,也会被多次调用。

atexit()注册限制

按照ISO C的规定,一个进程可以登记32个函数,这些函数由exit自动调用,通常这32个函数被称为终止处理程序,并调用atexit函数来登记这些函数。

下面我们验证一下,看是否有限制,我们沿用上述程序,注册35个函数:

func35()func34()func33()func32()func31()func30()func29()func28()func27()func26()

func25()func24()func23()func22()func21()func20()func19()func18()func17()func16()

func15()func14()func13()func12()func11()func10()func9()func8()func7()func6()

func5()func4()func3()func2()func1()

1

2

3

4

func35()func34()func33()func32()func31()func30()func29()func28()func27()func26()

func25()func24()func23()func22()func21()func20()func19()func18()func17()func16()

func15()func14()func13()func12()func11()func10()func9()func8()func7()func6()

func5()func4()func3()func2()func1()

其实是可以注册成功的。atexit()所能注册的函数是受堆寄存器唯一控制的,并不是一成不变的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值