程序异常结束导致内存未释放_你懂c语言的内存分布模型吗?一文详解内存分布模型...

什么是c语言的内存分布模型?

从本章开始,将引入费曼学习法来讲解一个概念9f54ab424c4d4955face42a9a74a69d1.png
只有自己明确了目标,通过讲述的方式,使得另外一个人也懂了,才算是真正懂了。
好了,言归正传,说c的内存分布模型,C的内存分布主要有5个:

  1. 堆(heap)

  2. 栈(stack)

  3. 全局(静态)存储区(Uninitialized data segment)

  4. 文字常量区(Initialized data segment)

  5. 程序代码区(Text)

内存布局如下(来源):84cf5b4d973c4c878b83b248a70c10c7.png

堆(heap)

堆是由程序员手动分配和释放,这个不同数据结构中的堆,分配方式类似链表,由malloc(C语言)或 new(c++)来分配,free(c语言)和delete(c++)释放,若程序员不释放,程序结束后由系统释放。

#include 
int main(void)
{
char *pStr = malloc(sizeof(char)*4); //使用malloc的堆上分配了空间,并用pStr指向这个堆空间,pStr是分配在栈上的
return 0;
}

栈(stack)

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

#include 
int main(void)
{
int data; //data 存储在栈上
return 0;
}

全局(静态)存储区(Uninitialized data segment)

DATA段存放初始化的全局变量和初始化静态变量,程序结束后由系统释放

#include 
int data1 = 10 ; //初始化的变量data1分配在data段
int main(void)
{
static int data2 = 3; //初始化的变量data2分配在data段
return 0;
}

全部未初始化区(Initialized data segment)

BSS段存放未初始化的全局变量和未初始化的静态变量,程序结束后由系统释放.
下述data1和data2都是在BSS段

#include 
int data1; // 未初始化的变量data1分配在bss段
int main(void)
{
static int data2; // 未初始化的变量data2分配在bss段
return 0;
}

程序代码区(Text)

程序代码区存放函数体的二进制代码

深入理解内存分布

给定一个例子说明内存分布

没有变量
#include  

int main(void)
{
return 0;
}

编译后查看

root@ubuntu:~# gcc -c test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
103 0 0 103 67 test-layout

发现bss段都为0,

局部静态未初始化区,存放bss段

在修改一下:

#include  

int main(void)
{
static int data; //在未初始化区bss
return 0;
}

再编译查看:

root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 544 8 1970 7b2 test-layout

bss段增加成8了

局部静态初始化区,存放data段

同样,将该值修改成一个初始化的值:

#include  

int main(void)
{
static int data = 100; //在初始化区data
return 0;
}

再编译查看:

root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 548 4 1970 7b2 test-layout

全局静态未初始化区,存放bss段

将data存放全局未初始化区:

#include  

int data; // 全局未初始化去

int main(void)
{
return 0;
}

编译查看:

root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 544 8 1970 7b2 test-layout

全局静态未初始化区,存放bss段
#include  

int data1; //Stored in uninitialized area,全局未初始化区

int main(void)
{
static int data2; //Stored in uninitialized area,全局未初始化区

return 0;
}

root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 544 16 1978 7ba test-layout

全局初始化和局部静态初始化,存放data段
#include  

int data1 = 0; //Stored in initialized area

int main(void)
{
static int data2 = 0; //Stored in initialized area

return 0;
}

编译查看:

root@ubuntu:~/# gcc test-layout.c -o test-layout
root@ubuntu:~/# size test-layout
text data bss dec hex filename
1418 544 16 1978 7ba test-layout

问题

在堆上,分配好的空间,若程序员不释放,程序结束由系统释放,那是不是可以不用释放,由系统释放就可以了

这个问题提出来很危险的,内存是有限的,若堆上的内存不释放,就会造成内存泄露,程序正常运行中没有可用的内存,就会导致系统异常,在平时的测试环境中没有释放内存,好像还看不出什么异常,但是,当程序在线上环境24小时运行,内存不断泄露导致没有可用的内存就会出现异常!

提炼

内存分布模型就是程序在运行中,变量存储位置的分布。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值