博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C/C++变量在内存中的位置以及初始化问题
阅读量:6885 次
发布时间:2019-06-27

本文共 1294 字,大约阅读时间需要 4 分钟。

首先我们给出内存布局

高内存地址

向下增长,可读可写可执行

空洞

向上增长

向上增长,可读可写可执行

BSS段(未初始化数据段)

向上增长,可读可写不可执行

.data 数据段

向上增长,可读可写不可执行

.text 文本段(代码段)

向上增长,可读可写不可执行

低内存地址

 

不同类型的变量在内存中的位置:

1,局部变量、函数参数存放在栈上。静态局部变量,并不是在调用函数时分配,在函数返回时释放,而是像全局变量一样静态分配在.data数据段,但它的作用域只在函数中起作用。

2,堆,给动态分配内存使用。

3,全局变量、静态变量位于.data数据段;未初始化变量则位于.bss未初始化数据段。

4const修饰的全局变量在.rodata只读数据段(const变量在定义时必须初始化,如果未初始化将被设为0或空),只读数据段在和.text同一个segment

5,代码段即存储程序文本。指令指针中的指令就从这里取得。这个段一般是可以被共享的:你可以使用两个编辑器(vi)来编辑文本,则它们共享一个代码段。

全局变量初始化和未初始化的区别

我们都知道未初始化的静态变量或全局变量将被初始化为空串或0;未初始化的局部变量的值不确定。

全局变量不初始化,则默认为0,存放在.bss数据段中。如int x = 0int x效果一样的。但是还是有差别的:

编译器在编译的时候针对这两种情况会产生两种符号放在目标文件的符号表中,对于初始化的,叫强符号,未初始化的,叫弱符号。

  连接器在连接目标文件的时候,如果遇到两个重名符号,会有以下处理规则:

  1、如果有多个重名的强符号,则报错。

  2、如果有一个强符号,多个弱符号,则以强符号为准。

  3、如果没有强符号,但有多个重名的弱符号,则任选一个弱符号。

基于以上规则,使用以下程序测试

1 #include 
2 3 int global_int; 4 void setInt(); 5 6 int main() 7 { 8 printf(“未初始化全局变量: %d\n”, global_int); 9 setInt();10 printf(“改变全局变量: %d\n”, global_int);11 }12 13 int global_int;14 15 void setInt()16 {17 global_int = 2;18 }

以上程序正常运行。如果将第2行和第12行的global_int任意一个初始化,程序也正常运行。但将第2行和第12行的gloal_int都初始化,将会出现:error: redefinition of ‘global_int’

所以我们尽量初始化全局变量。

除了连接有区别外,它们存储的位置也不一样:初始化的全局变量被保存在data数据段中;而未初始化的全局变量被保存在.bss数据段中。

转载于:https://www.cnblogs.com/jrun/archive/2012/10/02/2710255.html

你可能感兴趣的文章
openNebula rgister img instance vms error collections
查看>>
error Infos
查看>>
PL/sql配置相关
查看>>
Linux 查询服务数据
查看>>
【Luogu 2014】选课
查看>>
CSS 的介绍
查看>>
Latex自定义文档纸张大小
查看>>
2018QBXT刷题游记(23)
查看>>
函数递归
查看>>
android框架Java API接口总注释/**@hide*/和internal API
查看>>
20175318 2018-2019-2 《Java程序设计》第七周学习总结
查看>>
比特币:一种点对点的电子现金系统
查看>>
Android - 按钮组件详解
查看>>
MEF简单学习笔记
查看>>
Srping - bean的依赖注入(Dependency injection)
查看>>
工作中 Oracle 常用数据字典集锦
查看>>
SFB 项目经验-12-为某上市企业的Skype for Business购买Godday证书
查看>>
[C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型
查看>>
大数据虚拟化零起点-2基础运维第一步-环境规划和准备
查看>>
Skype for Business Server 2015-04-前端服务器-3-安装-管理工具
查看>>