C语言内存分布模型
什么是c语言的内存分布模型?
从本章开始,将引入费曼学习法来讲解一个概念
只有自己明确了目标,通过讲述的方式,使得另外一个人也懂了,才算是真正懂了。
好了,言归正传,说c的内存分布模型,C的内存分布主要有5个:
- 堆(heap)
- 栈(stack)
- 全局(静态)存储区(Uninitialized data segment)
- 文字常量区(Initialized data segment)
- 程序代码区(Text)
内存布局如下(来源):
堆(heap)
堆是由程序员手动分配和释放,这个不同意数据结构中的堆,分配方式类似链表,由malloc(C语言)或 new(c++)来分配,free(c语言)和delete(c++)释放,若程序员不释放,程序结束后由系统释放。
#include <stdio.h>
int main(void)
{
char *pStr = malloc(sizeof(char)*4); //使用malloc的堆上分配了空间,并用pStr指向这个堆空间,pStr是分配在栈上的
return 0;
}
栈(stack)
栈是由编译器自动分配和释放的,存放函数的参数值,局部变量等,操作方式类似数据结构中的栈。
#include <stdio.h>
int main(void)
{
int data; //data 存储在栈上
return 0;
}
全局(静态)存储区(Uninitialized data segment)
DATA段存放初始化的全局变量和初始化静态变量,程序结束后由系统释放
#include <stdio.h>
int data1 = 10 ; //初始化的变量data1分配在data段
int main(void)
{
static int data2 = 3; //初始化的变量data2分配在data段
return 0;
}
全部未初始化区(Initialized data segment)
BSS段存放未初始化的全局变量和未初始化的静态变量,程序结束后由系统释放. 下述data1和data2都是在BSS段
#include <stdio.h>
int data1; // 未初始化的变量data1分配在bss段
int main(void)
{
static int data2; // 未初始化的变量data2分配在bss段
return 0;
}
程序代码区(Text)
程序代码区存放函数体的二进制代码
深入理解内存分布
给定一个例子说明内存分布
没有变量
#include <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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小时运行,内存不断泄露导致没有可用的内存就会出现异常!
提炼
内存分布模型就是程序在运行中,变量存储位置的分布。
欢迎关注我的微信公众号: