全局静态变量、全局变量以及atexit回调的执行顺序

C++ 的析构与atexit()     曾经被问到过这样两个问题:1> 在C/C++中,怎样在程序退出main函数后仍然进行一些操作,比如资源堆栈方面的清理?2> 在C++程序中,我们要怎样才能够得到程序退出main后对象析构所需要的时间?     我们知道,在C++中,全局对象或者main域中对象的析构,是在退出main函数后进行的。所以对于问题1,我们可以在一个全局对象的析构函数中调用相关的函数来实现。但是, 阅读详情
版本

gcc version 7.5.0 (Ubuntu 7.5.0-6ubuntu2)
Linux UM480XT 5.15.0-107-generic #117~20.04.1-Ubuntu SMP Tue Apr 30 10:35:57 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Microsoft Visual Studio Enterprise 2019, _MSC_VER == 1929

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void on_exit()
{
    printf("%s()\n", __func__);
}

class Foo
{
public:
    Foo(int32_t i) :
        m_i(i)
    {
        printf("%s(%d)\n", __func__, m_i);
    }

    ~Foo()
    {
        printf("%s(%d)\n", __func__, m_i);
    }

    int32_t m_i = 0;
};

static Foo g_foo(1);

Foo g_foo2(2);

static Foo g_foo3(3);

void un_call()
{
    static Foo foo7(7);
    Foo foo8(8);
}

int main(int argc, char **argv)
{
    Foo foo7(7);
    static Foo foo4(4);
    Foo foo6(6);
    ::atexit(on_exit);
    static Foo foo5(5);
    printf("------\n");
    return 0;
}

在这里插入图片描述
与优化不优化无关系

顺序
构造函数调用顺序

全局变量/全局静态变量(按声明顺序构造) > 局部变量/局部静态变量(按声明顺序构造)

析构函数调用顺序

局部变量(先构造的后析构) > 在atexit函数后构造的局部静态变量 > atexit回调函数 > 局部静态变量(先构造的后析构) > 全局静态/全局变量(先构造的后析构)

不同源文件之间的 全局变量/全局静态变量 的构造顺序取决于链接顺序

如 test_1.cc test_2.cc两个文件
g++ test_1.cc test_2.cc -O2
那么先构造test_1文件的全局变量/全局静态变量,并且析构时间晚于test_2.cc
调换顺序后则先构造test_2

深度剖析c语言main函数---main函数的执行顺序   在之前的文章中,介绍了main函数的返回值 和 main函数的传参,本文主要介绍一下main函数的执行顺序。可能有的人会说,这还用说,main函数肯定是程序执行的第一个函数。那么,事实果然如此吗?相信在看了本文之后,会有不一样的认识。 为什么说main()是程序的入口   linux系统下程序的入口是”_start”,这个函数是linux系统库(Glibc)的一部分,当我们的程序和Gl... 阅读详情

相关推荐

科研党必备!用Requests+BeautifulSoup升级版Nature爬虫(含PDF下载功能)

本文介绍了一套基于Python Requests和BeautifulSoup的Nature期刊智能爬虫系统,专为科研人员设计,可自动抓取论文标题、摘要及开放获取的PDF文档。系统采用模块化设计,包含请求管理、PDF检测和邮件通知等功能,确保高效合规地获取学术资源,提升科研效率。

weixin_29041767的博客 255

c++ 局部变量 全局变量 atexit注册函数 析构顺序

析构先后顺序为:局部变量、mian函数中注册atexit函数、全局变量及在其中注册atexit函数(全局变量和在全局变量中注册atexit函数析构顺序与构造顺序相反)。测试代码如下(gcc-4.6.3编译, ubuntu 12.04 linux 内核3.2.0运行): #include #include #include #include static void PrintCurTim

whm2300的专栏 1853

水星路由器+群晖NAS+外网访问

水星路由器+群晖NAS+外网访问 有了公网IP,家里是水星路由器的 怎么设置外网访问 1.先电脑登录群晖的http://【你的群晖名】.quickconnect.to/ 2.【控制面板】进入设置 3.选择synology依次设置 ,【主机名称】就是你的名称。注意:左下角第7步,一定勾选。 4.下面进入192.168.1.1水星路由器设置。【IP与MAC绑定】点击NAS对应的【绑定】注意,点这里之前Nas一定设置了固定内网ip(后面补充 )。 5.【高级用户】-虚【拟服务器】。常用服务器不用选,其他的对应

wjxue201的博客 2597

全部变量、静态全局变量、类静态变量、atexit回调函数的调用顺序

巩固下c++基础,代码如下: #include #include #include #include std::vector structure; std::map info; class test1 { public: test1(){ structure.push_back(this); } ~test1(){ std::cout<<this<<"---~te

tank 1545

复现HumanMAC(HumanMAC: Masked Motion Completion for Human Motion Prediction)

Human3.6M和HumanEva-I都放到data目录下(记得将data_multi_modal-20250320T022408Z-001.zip和humaneva_multi_modal-20250320T022412Z-001.zip解压缩并且分别重命名为data_multi_modal和humaneva_multi_modal)。生成的gif存放在inference目录下zero_shot_<INDEX>下的out目录下。新建一个data目录,将

qq_52643100的博客 831

下采样新突破!ADown模块让YOLOv11多尺度特征提取更精准

ADown 凭借可编程梯度信息与多分支特征聚合的创新设计,打破了传统下采样在特征保留上的固有局限。本教程从原理到代码实现,再到工业场景适配,完整呈现了其在 YOLOv11 中的集成路径。只需简单新增模块脚本并修改配置文件,你的目标检测模型就能在多尺度特征捕捉能力上实现跨越式提升——无论是学术研究中的小目标检测突破,还是工业场景下的复杂多尺度任务落地,ADown 都能成为你攻克下采样瓶颈的利器。现在就动手尝试,让你的检测模型在下一代下采样技术的创新中再上一个台阶吧。

know_F0727的博客 524

main函数执行前后--全局构造和atexit

一直以来,程序都是从mian函数开始执行调试,我们会想当然认为main函数里面的代码就是程序的全部运行过程。事实上,main函数之前,程序已经开始运行了,main函数退出后,程序也并不一定就完全退出了。       C语言中的全局变量或者C++中的全局对象构造都会在main函数之前运行。而通过atexit函数注册,main函数之后也可以执行某些操作,比如释放某些资源,比如全局锁。如果注册多个at

faithzzf的专栏 943

多智能体系统在军事仿真中的应用:AI人工智能战略推演

本文旨在全面解析多智能体系统在军事仿真领域的应用技术,重点探讨AI驱动的战略推演系统的设计原理和实现方法。研究范围涵盖从基础理论到实际应用的完整技术栈。本文采用从理论到实践的递进结构,首先介绍核心概念,然后深入算法实现,最后展示实际应用案例和未来展望。多智能体系统(MAS):由多个相互作用的智能体组成的分布式系统军事仿真(Military Simulation):通过计算机模拟军事行动和战争场景战略推演(Strategic Wargaming):通过模拟推演评估军事战略的有效性更高保真度的仿真。

AI天才研究院 1777

通过一个示例看全局对象的构造和析构以及atexit的使用

通过一个macOS的可执行程序的示例去观察全局变量/对象的构造、析构的顺序,还有atexit的使用等等

技术的学习与积累是个技术活 598

华为OD机试真题2025双机位A卷 Java&Go 实现【采购订单】

在一个采购系统中,采购申请(PR)需要经过审批后才能生成采购订单(PO)。每个PR包含商品的单价(假设相同商品的单价一定是一样的)及数量信息。系统要求对商品进行分类处理:单价高于100元的商品需要单独处理,单价低于或等于100元的相同商品可以合并到同一采购订单PO中。针对单价低于100的小额订单,如果量大可以打折购买。

MISAYAONE的博客 1257

网络发生环路了,别慌,这些步骤一定要安排起来!

网络环路是指在计算机网络中,数据包因为某种原因在多个网络设备之间不断循环,形成了一个闭环。这样数据包就永远也无法到达目标,导致网络的流量滞留,设备间的资源耗尽,最终网络性能受到严重影响。网络环路虽然是常见的网络故障,但只要掌握正确的排查和解决方法,面对环路问题时,你就能冷静应对,迅速恢复网络的正常运行。希望这篇文章能帮助你更好地理解和处理网络环路的问题,让你的网络环境更加稳定可靠!🚀📡如果你有任何疑问,或者在实际操作中遇到困难,随时可以联系我,我们一起攻克技术难题!

网络技术联盟站 1965

C++全局变量和静态变量析构函数的执行时机

在C++中,对于局部变量,当局部变量的生命周期结束时,会自动调用析构函数。 但是对于全局变量和静态变量来说,其生命周期较长,其析构函数将会在什么时机进行调用呢?让我们来探究一下。 我们先看下面的一段程序: #include <iostream> #include <cstdlib> #include <string> class Static { public: Static() { std::cout << "Static

大脑白质的博客 3904

uniapp - [全端兼容] 实现精美Editor富文本编辑器功能,uniApp全平台兼容的富文本插件组件用户可上传图片及对接服务器存储文件等,手机移动端H5网页富文本/小程序富文本/App富文本!

uni-app,h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,uniapp富文本编辑器,uniapp中如何实现各平台都兼容的富文本编辑器,Editor富文本插件,uniApp微信小程序富文本,UNI-APP安卓苹果ios系统App端富文本组件,editor富文本编辑器如何实现上传图片,图片上传后不显示怎么办,如何配置图像上传功能,富文本图片上传怎么传到服务器中,获取图片路径,editor插入图片,富文本编辑器上传图片,报错怎么办,跨域CORS处理,配置不行无效

🏆 前端领域优质创作者 1万+

C++全局变量析构顺序终极指南

C++全局变量的静态析构顺序问题是一个经典陷阱,主要表现为跨源文件的全局变量析构顺序未定义,若存在依赖关系可能导致段错误。解决方法包括:将有依赖的变量放在同一源文件并按顺序定义;避免全局变量跨模块依赖;使用局部静态变量或单例模式;手动管理生命周期。建议谨慎处理全局变量依赖,代码评审时重点关注生命周期管理。参考资料包括C++ FAQ和《Effective C++》相关条目。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 538

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

exit()和atexit()函数

先从一个面试题说起: C

ziyuzhao123的专栏 1100

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

main函数执行前、后再执行的代码

一、main结束 不代表整个进程结束  (1)全局对象的构造函数会在main 函数之前执行,           全局对象的析构函数会在main函数之后执行;           用atexit注册的函数也会在main之后执行。   (2)一些全局变量、对象和静态变量、对象的空间分配和赋初值就是在执行main函数之前,而main函数执行完后,还要去执行一些诸如释放空间、释放资源使用权等操作   ...

zzhongcy的专栏 1496

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

避免执行某个函数atexit()的方法

为了避免替换进程映像后影响到当前进程的资源释放,通过fork子进程的方式,将我们不希望执行atexit的函数放到子进程中执行,在它之后要执行的函数仍在parent进程中执行,并等待子进程执行结束。通过 atexit 注册的函数会被存储在一个特定的数据结构中,这个结构是数据段的一部分。调用的一个外部函数中有atexit注册的函数,现因业务需求,不希望那个函数里通过atexit注册的函数被执行。因此在程序结束前,通过execl随便执行一个新进程替换当前的程序映像,便不会执行到atexit注册的函数。

qq_43079044的博客 877

[C++再学习系列] 全局或静态变量(对象)的初始化

全局或静态变量(对象)的初始化对于C语言的全局和静态变量,不管是否被初始化,其内存空间都是全局的;如果初始化,那么初始化发生在任何代码执行之前,属于编译期初始化。由于内置变量无须资源释放操作,仅需要回收内存空间,因此程序结束后全局内存空间被一起回收,不存在变量依赖问题,没有任何代码会再被执行! C++引入了对象,这给全局变量的管理带领

zhenjing的专栏 1748

全局变量,static变量初始化时间

原文 https://www.cnblogs.com/novice-dxx/p/7094690.html 本次上传主要是关于静态局部变量的初始化问题。 首先,静态局部变量和全局变量一样,数据都存放在全局区域,所以在主程序之前,编译器已经为其分配好了内存,但在C和C++中静态局部变量的初始化节点又有点不太一样。在C中,初始化发生在代码执行之前,编译阶段分配好内存之后,就会进行初始化,所以我们看到在C...

hueru的博客 2万+

C语言atexit函数:程序优雅退出的资源管理利器

在C语言程序开发中,资源管理是确保软件健壮性的核心基础。程序生命周期管理涉及内存、文件句柄、网络连接等系统资源的申请与释放,资源泄露是常见且难以排查的严重问题。atexit函数作为C标准库提供的机制,其原理是在程序正常终止时自动调用预先注册的清理函数,实现资源释放的自动化。这一技术价值在于将清理逻辑与业务逻辑解耦,通过栈结构的后进先出特性确保依赖资源的正确释放顺序,从而提升代码可维护性。在工程实践中,atexit适用于命令行工具、后台服务、嵌入式系统等需要确保资源安全释放的场景,是构建可靠系统软件的重要工具

weixin_33696822的博客 503

C语言在main执行之前和之后执行的一些操作

程序执行前后会执行一系列初始化与清理操作。在main函数执行前,操作系统会调用启动代码初始化环境,处理静态/全局变量,并执行构造函数(如GCC的__attribute__((constructor)))。main函数结束后,会执行atexit注册的清理函数(LIFO顺序)、析构函数(如__attribute__((destructor))),最后标准库完成缓冲区刷新等清理工作。整个过程确保程序资源正确初始化和释放。

弘羽 370

JoltPhysics中的静态变量析构顺序问题分析

在使用JoltPhysics物理引擎时,开发者可能会遇到一个与C++静态变量析构顺序相关的内存访问问题。这个问题特别容易出现在使用单例模式进行资源清理的场景中,或者当在程序退出时(通过atexit或静态变量析构)调用`UnregisterTypes`函数时。 ## 问题现象 当程序尝试在静态变量的析构函数中调用JoltPhysics的`UnregisterTypes`函数时,可能会触发"use...

gitblog_00217的博客 274

C语言atexit函数:程序退出时的资源清理与生命周期管理

在C语言程序开发中,资源管理是确保软件健壮性的核心环节。程序退出时,动态分配的内存、打开的文件句柄等资源若未妥善释放,会导致内存泄漏和资源耗尽问题。atexit函数作为C标准库提供的机制,允许开发者在程序正常终止前注册清理函数,实现自动化的资源回收。其遵循后进先出(LIFO)的执行顺序,确保了依赖关系的正确处理。这一机制在模块化设计、库开发和单元测试框架中具有重要价值,能够提升代码的可维护性和异常安全性。本文以atexit函数为例,深入探讨其在程序生命周期管理中的应用,涵盖资源清理、模块化设计等关键实践。

weixin_34072637的博客 322

5. C++ 局部静态变量在什么时候分配内存和初始化?

C++引入了对象,这给全局变量的管理带领新的麻烦。C++的对象必须有构造函数生成,并最终执行析构操作。由于构造和析构并非分配内存那么简单,可以说相当复杂,因此何时执行全局或静态对象(C++)的构造和析构呢?由于内置变量无须资源释放操作,仅需要回收内存空间,因此程序结束后全局内存空间被一起回收,不存在变量依赖问题,没有任何代码会再被执行!,在程序结束之后(如调用exit,main),按FILO顺序调用相应的析构操作!对于C语言的全局和静态变量,不管是否被初始化,其内存空间都是全局的;

谢谢大家的关注 1404

main函数执行前后可能执行哪些代码?

在 C++ 程序中,main函数执行之前和之后,分别会执行哪些代码?在 C++ 中,虽然main是程序的逻辑入口点,但程序在运行时会在main执行前进行环境初始化,在main执行后进行清理回收。

陈子青的博客 475
上一篇: liburing和Linux io_uring源码阅读
下一篇: C++ enum class实现& | ^ ~等操作
山有木兮啊
博客等级 码龄8年 135粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值