C语言内存四区模型(栈区、堆区以及全局区、还有凑数的代码区)
我们先不唠内存四区,就先来了解了解变量,从变量引入内存
我们知道定义一个变量,最基本的需要考虑两部分,数据类型和变量名,为什么要有数据类型?数据类型的存在是什么意义?难道就是单独为了刷存在感?绝对不是的,之所以是关键字,就是因为它们很关键。
先定义一个变量
int i;
我们sizeof一下这个变量名:
sizeof(i);
//4
我们sizeof一下这个数据类型:
sizeof(int);
//4
-----------------------------------
我们再定义一个变量
char c;
我们再sizeof一下这个变量名:
sizeof(c);
//1
我们再sizoof一下这个数据类型:
sizeof(char);
//1
-----------------------------------
我们再再定义一个变量:
double d;
我们再再sizeof一下这变量:
sizeof(d);
//8
我们再再sizeof一下这个数据类型:
sizeof(double);
//8
-----------------------------------
我们再再再定义一个变量:
double dd;
我们再再再sizeof一下这变量:
sizeof(dd);
//8
我们再再再sizeof一下这个数据类型:
sizeof(double);
//8
OK,以上是在同一台设备上的结果。
1、发现我们不管sizeof数据类型还是变量名,返回的字节大小都是该变量占用的内存大小。那么我们是否可以把这个变量的数据类型和变量名都来表示这块内存呢,同一块内存。
(好吧,这荔枝,确实有点生硬)
数据类型 变量名 = 值;
得出以下结论:
数据类型的本质:就是限定内存字节大小的别名。
变量名的本质:就是一块连续的内存的别名。
值就是这块内存中实际存储的内容。
(忽略那不懂事的logo)
变量的内存大小是通过数据类型决定的
数据类型其实就是个模具,而变量就是根据该模具创建出来的一个实物,实体存在的一块内存,值就是这个内存中实际存储的内容。
OK,不再探讨变量,这些我们都懂, 点到为止,只可意会不可言传。
我是有底线的
下面进入标题,内存四区
一个变量的内存四区模型,和该变量的作用域、生命周期都有着密不可分的关系。
(别看了,下面内存四区模型图都是文本)
内存四区分别为:
这个区域我们不关心。
我们来逐个分析一下,栈、堆、全局
代码区就当做来凑数的
------------栈区分析------------
栈区内存大小:
栈区存储的数据:
1、auto自动变量(也叫非静态局部变量)
2、函数的形参
3、函数的返回值
不可能拿空间换效率,永远不可能。
栈区内存的分配与释放:
释放:
栈区存储特点:
栈中出现数组:
栈的生长方向和数组内元素的存放方向相反
如果函数的返回值是指针时:
栈区内存四区模型:
void fun(){
int a = 10; //变量a
int b = 20; //变量b
int c = 30; //变量c
int arr[5] = {1,2,3,4,5}; //数组arr
}
我也是有底线的
------------堆区分析------------
堆区内存大小:
堆区内存的分配与释放:
分配:
1、先进先出,后进后出
存储和栈相反,和堆相同。
栈的生长方向和数组内元素的存放方向相反。堆的生长方向和数组内元素的存放方向相同。
堆区内存四区模型:
int *getMem(){
int *temp = (int*)calloc(5,sizeof(int));
return temp;
}
int main(){
int a = 10;
int *p = (int *)malloc(sizeof(int));
*p = 1;
int *arr = getMem();
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
free(p);
free(arr);
p = NULL;
arr = NULL;
return 0;
}
我也是有底线的
------------全局区分析------------
全局区大小:
是一个全局的,整个程序的全局,应该挺大的吧,你品,你细品,啊哈哈哈哈哈~
全局区存储的数据:
全局区内存的分配与释放:
全局区存储特点:
全局变量和静态变量的存储是存放在全局区中的静态区中。
未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,该区域在程序结束后由操作系统释放。
初始化的全局变量和静态变量在一块区域。
全局区一般只分静态区和常量区:
常量区特点:
如果程序中,多次定义了相同的字符串常量,并且在不同的函数体内,赋值给了不同的变量。其本质是只存在一个。
char *str1 = "abcd";
char *str2 = "abcd";
//通过这些指针变量的指向的内存地址,可以得出,是同一个。
//不信你试试
出现相同字符串常量时的内部操作:
第一次定义该字符串常量的时候,加载到全局区的字符串常量区中。
所以,字符串常量,在内存中,是唯一的。
需要注意的是:
全局区内存四区模型:
char *get_str1(){
char *p = "abc";
return p;
}
char *get_str2(){
char *p = "abc";
return p;
}
int a; //全局变量a
int main(){
char *p = NULL;
char *q = NULL;
static int b; //静态局部变量
p = get_str1();
q = get_str2();
return 0;
}
我也是有底线的
OK,以上就是内存四区的总结和模型,最重要的就是堆内存和栈内存,一定要区分开它的存储方式。
写的代码,多用内存四区画出来,脑壳里要有比较清晰的认识。
最后最后,奉上小编当时学内存四区时画的几张图图:
------------我真的是有底线的-----------
(在线卑微求关注,别走啊,取消推送也行啊~)