对栈区、堆区、bss区、代码区的理解jikuo_wang

计算机中的内存按字节编址

每个地址的存储单元可以存放一个字节(8个bit)的数据

cpu通过内存地址获取指令和数据

并不关心这个地址所代表的空间具体在什么位置,怎么分布,

因为硬件的设计保证一个地址对应着一个固定的空间。

即:内存地址和地址指向的空间共同构成了一个内存单元

-----------------------------------

C语言编写的程序而言,内存主要分为5部分

(1)栈和(2)堆是运行时   系统分配的空间

(3)BSS段(未初始化)、(4)数据段(已初始化)、(5)代码段是由编译器分配空间

 

==============================

BSS段、数据段、代码段是由编译器分配空间,在程序启动时加载

由于未初始化的全局存放在BSS段,

已初始化的全局变量存放在数据段

程序中应该   尽量少的使用全局变量一节省程序编译和启动时间

全局变量是只要进程存在就会一直存在,一直占用内存

全局变量在程序启动的时候才会去加载,所以全局变量不能太多

太多会增加启动时间 和 增加编译时间(打包时间变长)

===============

详解:

对栈区、堆区、bss区、代码区的理解jikuo_wang

 

 

 

 

===================================

静态存储区

只读数据区,读写数据区,未初始化区(BSS)

都是在程序编译连接阶段确定的,在程序执行的阶段不会改变

=============================

动态存储区

分为堆和栈

都是执行的过程中动态分配的,大小也随之动态的变化

从内存管理的实现的角度看来,堆使用的链表实现的,而栈使用的是线性存储的方法

===========================

1.栈 stack: 系统分配空间

==============================

先进后出原则  (手枪的子弹)

通过不断移动栈顶指针来实现子弹的装载荷发射

其次栈作为内存中存储结构,通常存放程序的临时创建的局部变量

即函数大括号    { }   中定义的变量,其中还包括函数调用时其形参,和调用后的返回值

栈是由高地址向地址扩展的数据结构

最后   栈 还具有“小内存、自动化、可能会溢出”的特点

栈顶的地址和栈最大容量一般是系统预先规定好的,通常不会太大

由于栈中存放的是局部变量,而局部变量的占用的内存空间是其

所在代码段或函数段结束时由系统回收重新利用

所以栈的空间是循环利用自动管理的,一般不需要认为操作

如果某次局部变量申请的空间超过栈的剩余空间就有可能出现

“栈的溢出”,一般不在栈中申请过大的空间,比如长度很大的数组

递归调用重复次数很多的函数

2.堆区(heap):由程序员分配释放

==========================

若程序员不释放,程序结束时由OS回收,

如果程序员在使用完申请后的堆内存却没有及时把它释放掉,

那么这块内存就丢失了。(进程认为该内存没有被使用,但是

在堆内存记录中该内存仍然属于这个进程,所以当需要分配空间时

又会重新去申请新的内存二不是重复利用这块内存)

就是我们常说的内存泄露

内存的分配不是连续的,类似于链表。

Heap: 堆,*申请的空间,按内存地址由低到高方向生长,

其大小由系统内存/虚拟内存上限决定,速度较慢,但*性大,可用空间大。

每个线程都会有自己的栈,但是堆空间是共用的。

(1)通常存放程序运行中动态分配的存储空间;

(2)堆是低地址向高地址扩展的数据结构,是一块不连续的内存区域;

(3)使用 malloc 和new在堆中分配内存

 

3.BSS段 block started by symbol

=============================

通常是指用来存放程序中未初始化的全局变量和静态变量

静态分配,在程序开始时通常会被清零。

静态变量:用static修饰的

4.数据段

=======

通常是指用来存放程序中已初始化的全局变量和静态变量以及字符串常量

5.代码段

=======

通常是指用来存放程序执行代码的一块内存区域

这部分区域的大小在程序运行前就已经确定。

=========================================

 

int a = 0; //全局初始化区 

char *p1; //全局未初始化区 

void main() 

{

    int b; //栈 

    char s[] = “abc“;//栈 

    char *p2; //栈 

    char *p3 = “123456“; //123456\0在常量区,p3在栈上;体会与 char s[]="abc"; 的不同

    static int c =0; //全局初始化区 

    p2 = (char *)malloc(20); //堆区

    strcpy(p1, “123456“); //123456\0在常量区,编译器可能将它与p3指向的 “123456 “优化成一块

}

 

=====================================

over