银川网站建设联系电话百度快速查询
2026/4/18 10:08:17 网站建设 项目流程
银川网站建设联系电话,百度快速查询,wordpress修改自适应,网站后台管理系统怎么用前言#xff1a;童鞋们有没有遇到过程序已启动就莫名地崩溃了#xff1f;很多时候SIOF#xff08;Static Initialization Order Fiasco#xff09;是罪魁祸首。今天来讲讲静态初始化顺序问题。 目录 一、先看个例子 二、初始化逻辑 2.1 静态初始化 2.2 动态初始化 三、…前言童鞋们有没有遇到过程序已启动就莫名地崩溃了很多时候SIOFStatic Initialization Order Fiasco是罪魁祸首。今天来讲讲静态初始化顺序问题。目录一、先看个例子二、初始化逻辑2.1 静态初始化2.2 动态初始化三、如何避免3.1 判断是否是全局初始化阶段导致的崩溃3.2 推荐的解决措施一、先看个例子假如我们有一个全局单例在logger.cpp文件中// logger.cpp class Logger { public: void log(const char* msg); }; Logger g_logger; // 全局对象在另一个service.cpp文件中使用了上面的g_logger全局对象// service.cpp extern Logger g_logger; class Service { public: Service() { g_logger.log(Service started); } }; Service g_service;童鞋们看出上面代码中的问题了吗在对g_service对象进行构造的时候很容易导致崩溃为什么呢如果g_looger对象先于g_service对象初始化那么就是安全的。那如果g_logger对象初始化在后那么可怕的崩溃就发生了这就是初始化顺序问题导致的灾难。对于上述两个对象初始化谁先谁后其实是无法保证的因为它们在两个不同的源文件中编译器的链接顺序是不确定的。【注在同一源文件中的全局对象初始化是按照其定义顺序进行的】二、初始化逻辑C把全局、静态变量(非局部)的初始化分为两种2.1 静态初始化零初始化内存清0常量初始化编译器就能够确定的常量表达式如int num 2; const double pi 3.14159;这类初始化是程序启动前就完成了几乎不会产生什么问题。2.2 动态初始化运行时的初始化如调用构造函数如第一节中列举的例子函数返回值初始化如int num caculate();这类初始化在程序一启动时候执行在主程序之前如main()。如果不注意初始化顺序很容易出现程序崩溃问题。三、如何避免3.1 判断是否是全局初始化阶段导致的崩溃全局初始化阶段崩溃一般调用栈会出现以下关键字眼_init_term、__static_initialization_and_destruction_* global constructors keyed to dynamic initializer for3.2 推荐的解决措施使用函数内的静态局部变量其特点是首次进入时才进行构造初始化顺序由调用流决定线程安全C11及之后。根据这个思想将第一节中的代码 进行优化// logger.cpp class Logger { public: void log(const char* msg); }; Logger getLogger() { static Logger m_log; //静态局部首次调用时构造线程安全C11 return m_log; }// service.cpp class Service { Service() { getLogger().log(Service started); // 此时保证 Logger 已初始化 } }; Service g_service; // 仍然可以是全局但它内部访问的是函数内 static这就简单、完美地解决了初始化顺序导致的崩溃灾难感兴趣的童鞋可关注作者公众号定期同步

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询