第一次写博客之类的东西,主要是为了记录自己的学习过程,以便于记忆的加深和与各位大神进行探讨,学习更多的东西。

  

本次上传主要是关于静态局部变量的初始化问题。

首先,静态局部变量和全局变量一样,数据都存放在全局区域,所以在主程序之前,编译器已经为其分配好了内存,但在C和C++中静态局部变量的初始化节点又有点不太一样。在C中,初始化发生在代码执行之前,编译阶段分配好内存之后,就会进行初始化,所以我们看到在C语言中无法使用变量对静态局部变量进行初始化,在程序运行结束,变量所处的全局内存会被全部回收。而在C++中,初始化时在执行相关代码时才会进行初始化,主要是由于C++引入对象后,要进行初始化必须执行相应构造函数和析构函数,在构造函数或析构函数中经常会需要进行某些程序中需要进行的特定操作,并非简单地分配内存。所以C++标准定为全局或静态对象是有首次用到时才会进行构造,并通过atexit()来管理。在程序结束,按照构造顺序反方向进行逐个析构。所以在C++中是可以使用变量对静态局部变量进行初始化的。

后面再来谈谈另一个问题,假如我们在一个循环中,定义了一个静态局部变量并进行初始化,循环过程中,编译器怎么知道当前的静态局部变量已经初始化过了呢?

这个问题C和C++的处理方式也是不一样的。C中编译器会直接跳过这一个语句,因为在编译的时候已经对静态局部变量进行过分配空间并初始化,所以代码执行过程中根本不需要再次执行。而在C++中,编译器会在编译器分配内存后,在全局区域(当前静态局部变量的地址)附近同样分配一块空间,进行记录变量是否已经进行过初始化。之所以说附近是根据编译器不同,处理方式不同导致的。在网上有博客介绍某种编译器(该吧主并没有透露编译器名字),会在当前变量后面的一个字节进行改变,具体上代码:

(Ps:若编译器已经发现当前变量初始化,则直接将整行代码跳过,若等式后面为n++,则不会继续执行++命令)

从地址内存中我们可以看到在变量地址的后面一个字节中,有一个01用来记载当前静态变量是否初始化。

而在VS2012中,发现了一个很奇怪的现象,先上代码。

这段代码a为变量,右侧为执行代码的汇编语句,可以看到先从0x00306214中提取出来值,如果是0,则会继续执行,进行初始化,如果是1,则会跳过当前下面的动作,此处可以看到标志位地址是在变量地址之前0x80个字节,但继续后面几种情况

可以看到只要变量名称发生改变,每次标志位所在的地址与变量地址之间的差距变化都比较大。可见VS编译器对标志位地址的选择是根据变量名称变化的。具体选择方法,还希望有钻研过的大神指点一二。

上面说到的仅仅针对单线程的程序,如果在多线程下的执行,g++编译器会在在初始化过程中对标志位进行加锁控制,详情参考一下 http://www.cnblogs.com/xuxm2007/p/4652944.html

在不确定编译器是否会对多线程环境下静态局部变量初始化加锁的情况下,尽量不要使用初始化的局部静态变量,如果需要使用,则需要自己定义一个全局锁进行管控,如一个线程正在对某个变量(对象)进行构造,另一个线程需要直接避开构造。

第一次发此类分享类博客,如果有大神看出其中漏洞,请及时指出,以便于本人能够对这方面的了解更加深入

补充:使用G++调试后,查看地址发现对于一个静态局部变量,编译器会开辟8个字节的大小的存放空间,同时存放位置刚好在变量前面的8个字节位置。若有两个静态局部变量,则从第一个静态局部变量前16个字节,分别8个字节对应一个变量。用事实说话,上图:

static静态局部变量初始化问题的更多相关文章

  1. static静态全局变量和static静态局部变量

    static静态全局变量: 静态全局变量就是将全局变量变成静态的.如何变?——全局变量加个static. static就是一个存储类说明符,a这个全局变量就成了一个静态全局变量了. 静态全局变量的特点 ...

  2. PHP static静态局部变量和静态全局变量总结

    1.不会随着函数的调用和退出而发生变化,不过,尽管该变量还继续存在,但不能使用它.倘若再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值 2.静态局部变量只会初始化一次 3.静态属 ...

  3. PHP之static静态变量详解(一)

    什么是static静态变量?(以下为在C语言中的理解) 静态变量 类型说明符是static. 静态变量属于静态存储方式,其存储空间为内存中的静态数据区(在静态存储区内分配存储单元),该 区域中的数据在 ...

  4. c语言局部变量 静态局部变量 全局变量与静态全局变量

    基本概念: 作用域:起作用的区域,也就是可以工作的范围. 代码块:所谓代码块,就是用{}括起来的一段代码. 数据段:数据段存的是数,像全局变量就是存在数据段的 代码段:存的是程序代码,一般是只读的. ...

  5. 静态局部变量(面向过程的static关键字)

    对于一个完整的程序,在内存中的分布情况如下图: 一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区.自动变量一般会随函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量) ...

  6. 单片机之静态局部变量static

    HL-1慧静电子 上程序: main.c #include <reg52.h>#include "Timer.h" /********P1口低有效*********** ...

  7. C++ 全局变量、局部变量、静态全局变量、静态局部变量的区别

    全局变量.局部变量.静态全局变量.静态局部变量的区别 C++变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作 ...

  8. static静态变量的理解

    静态变量 类型说明符是static.静态变量属于静态存储方式,其存储空间为内存中的静态数据区(在 静态存储区内分配存储单元),该区域中的数据在整个程序的运行期间一直占用这些存储空间(在程序整个运行期间 ...

  9. 静态局部变量、静态全局变量、extern全局变量、自动变量 札记

    静态局部变量 静态局部变量. 从称呼上我们可以看出,静态局部变量首先是一个局部变量,因此其只在定义它的函数内有效,冠以静态的头衔后,其生存期就被延长了,不会随着函数的返回而被撤销.我们可以这样来理解: ...

随机推荐

  1. POJ1742Coins

    题目:http://poj.org/problem?id=1742 可以正常地多重背包.但是看了<算法竞赛入门经典>,收获了贪心的好方法. 因为这里只需知道是否可行,不需更新出最优值之类的 ...

  2. Web自动化测试框架Watir(基于Ruby) - 第2章 使用Watir写自动化测试脚本

    一.先来看一个小DEMO 通过上一篇博文<Web自动化测试框架Watir(基于Ruby) - 第1章 Windows下安装与部署>的介绍,我们已经有了完整Watir运行环境,现在我们可以来 ...

  3. C#获取本机IP地址(ipv4)

    获取本机所有IP地址: 这些地址是包含所有网卡(虚拟网卡)的ipv4和ipv6地址. string name = Dns.GetHostName(); IPAddress[] ipadrlist = ...

  4. Angular 4.0 环境搭建

    1.安装node 2.angular cli安装 sudo npm install -g @angular/cli 3. 使用ng -v 查看安装结果 4. 创建项目 ng new helloworl ...

  5. Mac 下 IDEA 中 SpringBoot 如何利用 DevTool 开启热部署

    一.首先 pom.xml 中  依赖 和 构建 部分 二.IDEA 配置 注意这一步一定不要改错地方,认准 IntelliJ IDEA -> Preferences… 三.退出 IDEA 编辑器 ...

  6. 【Hibernate学习笔记-5.1】使用@Transient修饰不想持久保存的属性

     作者:ssslinppp       1. 摘要 在默认情况下,持久化类的所有属性会自动映射到数据表的数据列.如果在实际应用中不想持久化保存某些属性,则可以考虑使用@Transient来修饰他们. ...

  7. CentOS命令行性能检测工具

    一.uptime Uptime命令的显示结果包括服务器已经运行了多长时间,有多少登陆用户和对服务器性能的总体评估(load average).load average值分别记录了上个1分钟,5分钟和1 ...

  8. (转!)大话websocket

    邪正看眼鼻,真假看嘴唇,功名看气概,富贵看精神. ---曾国藩<冰鉴> 转自https://www.cnblogs.com/fuqiang88/p/5956363.html 原文http: ...

  9. VMware中,该如何理解桥接网络与NAT 网络模式

    原创 2016年11月16日 23:26:34,原文地址如下: http://blog.csdn.net/u010801439/article/details/53193113 首先,我在VMware ...

  10. Jade模板引擎使用详解

    在 Express 中调用 jade 模板引擎 jade 变量调用 if 判断 循环 Case 选择 在模板中调用其他语言 可重用的 jade 块 (Mixins) 模板包含 (Includes) 模 ...