C/C++程序内存布局(data段,bss段,text段)以及static关键字详解

1.内存布局

1.1 data段(可读可写)

data包含静态初始化的数据,所以有初值的全局变量和static变量在data区。段的起始位置也是由连接定位文件所确定,大小在编译连接时自动分配,它和程序大小没有关系,但和程序使用到的全局变量,常量数量相关

1.2 text段(只读)

text段是程序代码段,在AT91库中是表示程序段的大小,它是由编译器在编译连接时自动计算的,当你在链接定位文件中将该符号放置在代码段后,那么该符号表示的值就是代码段大小,编译连接时,该符号所代表的值会自动代入到源程序中

1.3 bss段(可读可写)

bss是英文Block Started by Symbol的简称,通常是指用来存放程序中未初始化的全局变量的一块内存区域,在程序载入时由内核清0。BSS段属于静态内存分配。

1.4 堆区

堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表

1.5 栈区

由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈

1.6全局区/静态区

全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(.data段),未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(.bss段)。 - 程序结束后有系统释放。

注:在采用段式内存管理的架构中(比如intel的80x86系统),.bss段(Block Started by Symbol segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时bss段部分将会清零。bss段属于静态内存分配,即程序一开始就将其清零了。在C语言之类的程序编译完成之后,已初始化的全局变量保存在.data 段中

1.7 字符串常量区

文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放

1.8 代码区

存放二进制代码

1.9 注意

一个程序的3个基本段:text段,data段,bss段。

①text段在内存中被映射为只读,但.data和.bss是可写的。

  text段:就是放程序代码的,编译时确定,只读;

②data段:存放在编译阶段(而非运行时)就能确定的数据,可读可写。也就是通常所说的静态存储区, 赋了初值的全局变量和赋初值的静态变量存放在这个区域,常量也存放在这个区域;

③bss段:定义而没有赋初值的全局变量和静态变量,放在这个区域

在这里插入图片描述

int a = 0; 全局初始化区   
char *p1; 全局未初始化区   
main()   
{   
  int b;char s[] = "abc";char *p2;char *p3 = "123456"; 123456/0在常量区,p3在栈上。   
  static int c =0; 全局(静态)初始化区   
  p1 = (char *)malloc(10);   
  p2 = (char *)malloc(20);//分配得来得10和20字节的区域就在堆区。   
  strcpy(p1, "123456"); 123456/0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。   
}  

2.static关键字

2.1 概括:

c/c++共有

       1):修饰全局变量时,表明一个全局变量只对定义在同一文件中的函数可见。                         

       2):修饰局部变量时,表明该变量的值不会因为函数终止而丢失。              

       3):修饰函数时,表明该函数只在同一文件中调用。

c++独有:

       4):修饰类的数据成员,表明对该类所有对象这个数据成员都只有一个实例。即该实例归 所有对象共有。

       5):用static修饰不访问非静态数据成员的类成员函数。这意味着一个静态成员函数只能访问它的参数、类的静态数据成员和全局变量

2.2 详解

  1. 全局静态变量
    在全局变量前加上关键字static,全局变量就定义成一个全局静态变量.静态存储区,在整个程序运行期间一直存在。
    初始化:未经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化);
    作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾。
  2. 局部静态变量
    在局部变量之前加上关键字static,局部变量就成为一个局部静态变量。内存中的位置:静态存储区
    初始化:未经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化);
    作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域结束。但是当局部静态变量离开作用域后,并没有销毁,而是仍然驻留在内存当中,只不过我们不能再对它进行访问,直到该函数再次被调用,并且值不变;
  3. 静态函数
    在函数返回类型前加static,函数就定义为静态函数。函数的定义和声明在默认情况下都是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。函数的实现使用static修饰,那么这个函数只可在本cpp内使用,不会同其他cpp中的同名函数引起冲突;
    warning:不要再头文件中声明static的全局函数,不要在cpp内声明非static的全局函数,如果你要在多个cpp中复用该函数,就把它的声明提到头文件里去,否则cpp内部声明需加上static修饰;
  4. 类的静态成员
    在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。对多个对象来说,静态数据成员只存储一处,供所有对象共用
  5. 类的静态函数
    静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名
    在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员(这点非常重要)。如果静态成员函数中要引用非静态成员时,可通过对象来引用。从中可看出,调用静态成员
    函数使用如下格式:<类名>::<静态成员函数名>(<参数表>);
    并且从根本原因上看,static修饰的变量等,在编译时期,并不生成符号,那么是没有办法进行链接的。
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在计算机系统中,程序(Program Segment)是指编译器在编译程序时将程序中的所有元素分成的一些组成部分,其中包括代码、数据bss。代码程序中的可执行部分,即函数堆叠组成的部分。数据程序中的数据,包括全局变量。而bss是用来存放未初始化的全局变量的一块内存区域,通常被初始化为0。\[1\] 在这些中,数据(.data)用来存放显示初始化为非零的全局变量,而bss用来存放显式初始化为0或者未显式初始化的全局变量(C语言规定未显式初始化的全局变量值默认为0)。\[1\] 关于pcb程序data的具体区别,根据提供的引用内容,没有明确的信息可以回答这个问题。请提供更多相关的信息或引用内容,以便我能够给出更准确的答案。 #### 引用[.reference_title] - *1* [三种内存来源:栈(stack)、堆(heap)、数据区(.data)、bss](https://blog.csdn.net/weixin_45623808/article/details/107851457)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [(深入理解计算机系统) bssdatatext、堆(heap)和栈(stack)](https://blog.csdn.net/yuhoujiangnan2011/article/details/123467996)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值