内存分区
1、整体框图
内存分为代码区、全局区、栈区、堆区。代码区和全局区在代码编译完之后就已经确定,栈区和堆区是在程序运行时进行开辟和释放的。整体内存分区框图如下:
对于一个进程,它一共有4G的空间,其中0~3G为上述的4个区(用户空间)、3G~4G为内核空间。
2、各区的含义
2.1 代码区
代码区存放的是函数体的二进制代码,由操作系统进行管理,具有共享、只读的特征。
即:存放的是我们自己写的代码通过编译后生成的cpu执行的机器指令。
2.2 全局区
全局区又叫全局静态区,存放的是全局变量、静态变量(static)、常量(const)
全局区的生命周期直到程序结束,这代表全局区的数据会一直占用空间,也代表变量随时可以访问
全局区中又分为三个区,从低地址到高地址分别为文字常量区、初始化数据区、未初始化数据区。
其中:未初始化区是指 " 没有初始化 " 或 " 以0为初始值 "的情况。具体的框图如下:
2.3 栈区
栈区是由编译器自动分配释放,存放函教的参数值、局部变量等
栈区的生命周期为函数内部
2.4 堆区
由程序员分配和释放,若程序员不释放程序结束时由操作系统回收
堆区的生命周期由程序员主动释放,或程序结束自动释放
使用size查看可执行文件的内存占用情况
指令:size <可执行文件名>,单位为字节
堆区操作
注意:malloc与free必须成对出现,否则会造成内存泄漏
1、动态申请堆区空间malloc
头文件:
#include <stdlib.h>
使用方法:
<指针> = <类型强转>malloc(sizeof(类型)*空间大小);
//申请一个大小为5个的char类型的空间
char *p = NULL;
p = (char*)malloc(sizeof(char)*5);
if(p==NULL){
printf("malloc failled");
}
2、释放申请从堆区空间free
头文件:
#include <stdlib.h>
使用方法:
//释放malloc申请的空间
free(p);//p指向malloc申请的空间
3、示例代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char *p = NULL;
//1.malloc开辟空间,并检测是否开辟成功
p = (char*)malloc(sizeof(char)*5);
if(p==NULL){
printf("malloc failed\n");
exit(-1);
}
//2.使用开辟的空间
strcpy(p,"abc");
printf("p = %s\n",p);
//3.释放开辟的空间
free(p);
return 0;
}
内存泄漏与内存溢出
内存泄漏(memory leak):
内存泄漏是指申请的内存空间使用完毕之后未回收,即:没有进行free
一次内存泄露危害可以忽略,但若一直泄漏,无论有多少内存,迟早都会被占用光,最终导致程序crash。(因此,开发中我们要尽量避免内存泄漏的出现)
内存溢出(out of memory):
内存溢出是指程序在申请内存时,没有足够的内存空间供其使用。即:内存不够用
通俗理解就是内存不够用了,通常在运行大型应用或游戏时,应用或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。最终导致机器重启或者程序crash。