avatar

目录
static变量的存储与初始化时间

数据段探究

数据段主要分为.bss(Block Started by Symbol)和.data(data segment)段,前者指用来存放程序中未初始化的全局变量的一块内存区域,后者是指用来存放程序中已初始化的全局变量的一块内存区域。
text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载 ,我们用段代码来确定
程序1:

c++
1
2
3
4
5
int ar[30000];
int main()
{
return 0;
}

程序二:

c++
1
2
3
4
5
int ar[30000];
void main()
{
return 0;
}

程序一的大小:
程序二的大小:

全局静态变量

我们先来看全局的静态变量,我们考虑初始化和未初始化两种情况,很明显他们存在.data段,并且是在程序加载进入main函数之前就初始化了,比如单例模式里的恶汉模式,所以就不必担心多线程问题

  • 初始化:
c++
1
2
3
4
static int test = 1;
int main() {
return 0;
}
Code
1
2
3
4
5
6
7
sunxin@sunxin-KLVC-WXX9:~/static$ g++ test.cpp -g
sunxin@sunxin-KLVC-WXX9:~/static$ gdb a.out

(gdb) info addr test
Symbol "test" is static storage at address 0x201010.
(gdb) info symbol 0x201010
test in section .data

可以看到初始化的静态变量存在.data段,所以是在程序加载进入main函数之前就初始化了,由此也可以联想到单例模式里的恶汉模式,所以就不必担心多线程问题

如果没有赋值的全局静态变量是初始化在.bss里的:

c++
1
2
3
4
static int test;
int main() {
return 0;
}
Code
1
2
3
4
(gdb)  info addr test
Symbol "test" is static storage at address 0x201018.
(gdb) info symbol 0x201018
test in section .bss

接下来看一种在函数中初始化的全局静态变量,发现也是存在.bss区。

c++
1
2
3
4
5
6
7
int foo() {
return 1;
}
static int test = foo();
int main() {
return 0;
}
Code
1
2
3
4
(gdb) info addr test
Symbol "test" is static storage at address 0x201138.
(gdb) info symbol 0x201138
test in section .bss

对于以上代码,通过调试,我发现进入main函数前,test的值已经初始化为0了,进入main函数后test为1,说明 .bbs存储的是全局未初始化的变量,系统初始化为0当做一个占位符,而.data存的是初始化为自定义的变量

局部静态变量

关于局部静态变量的初始化就有些疑惑了,在c里静态变量都是在编译期间初始化完成,但是c++里就不太清楚了,网上很多答复是对象首次用到的时候构造初始化,接下来的代码我们来探究一下:
首先写个简单的局部静态变量

c++
1
2
3
4
5
6
7
8
#include<iostream>
using namespace std;
int main() {
static int test = 1; //存在.data
static int no_test; //存在.bss
static int no_test_2 = 0//存在.bss
return 0;
}
Code
1
2
3
4
5
6
7
8
(gdb) disas main
Dump of assembler code for function main():
0x000000000000073a <+0>: push %rbp
0x000000000000073b <+1>: mov %rsp,%rbp
0x000000000000073e <+4>: mov $0x0,%eax
0x0000000000000743 <+9>: pop %rbp
0x0000000000000744 <+10>: retq
End of assembler dump.

通过汇编看不到main函数里对static变量初始化的语句,但进main函数前是查不到test的值的,说明局部静态变量是程序第一次碰到他的定义的时候,之后通过类似上面的办法,得出了静态变量的存储位置详见注释

类中静态变量

不多废话,直接通过代码分析:

c++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class test
{
public:
test(const char *name)
: _name(name) {
cout << _name << " created" << endl;
}
~test(){
cout << _name << " destroyed" << endl;
}
string _name;
};
test t("global variable");
void f()
{
static test t("static variable");
test t2("Local variable");
cout << "Function executed" << endl;
}
int main()
{
test t("local to main");
cout << "Program start" << endl;
f();
cout << "Program end" << endl;
return 0;
}
Code
1
2
3
4
5
6
7
8
9
10
11
global variable created
local to main created
Program start
static variable created
Local variable created
Function executed
Local variable destroyed
Program end
local to main destroyed
static variable destroyed
global variable destroyed

参考文献:https://www.cnblogs.com/mylinux/p/5611225.html
https://stackoverflow.com/questions/55510/when-do-function-level-static-variables-get-allocated-initialized

文章作者: Sunxin
文章链接: https://sunxin18.github.io/2021/08/03/static/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 lalala
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论