第十五章 内存的五大区域
内存中的五大区域
分别说明
- 栈区(先进后出)
- 由编译器自动分配并释放,存放函数的参数值,局部变量,一旦出了作用域就会被销毁;
- 栈区地址从高到低分配;
- 特点:
- 存储空间有限:iphone的栈区大小只有512k(默认) ,非常有限
- 栈区的地址是连续的
- 地址分配从大到小. 栈区地址按照分配的顺序,由大到小顺序排列
- 访问速度快.
- 系统管理. (栈区的内存由系统管理)
- 堆区
- 程序员手动的从堆申请空间来使用。我们堆中申请的字节空间,如果我们不主动释放,那么系统是不会释放的,除非程序结束
- 虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存/释放内存匹配是良好程序的基本要素。
- 堆区的地址是从低到高分配)
- 特点:
- 所有程序共享
- 存储大数据
- 程序员管理: 堆区的内存需要程序员管理
- 不连续: 堆区的地址是不连续的
- 速度没有栈区快: 堆区的访问速度没有栈区快,因为我们要访问堆区中创建对象的属性,必须先需要通过变量找到栈区的地址,再通过地址定位到到堆区中的某一个位置,只有找个这个位置之后,我们才可以访问到存储到这个对象中属性对应的数值.由于有了这个地址寻找的过程,所有速度没有栈区的快.
- BSS段
- 用来存储未初始化的全局变量和静态变量,声明一个全局变量,如果我们没有初始化,在程序运行最开始的时候,这个变量没有初始化时是存储在BSS段,初始化之后,全局变量和静态变量就会被放到常量区。
- 数据段/常量区
- 用来存储已经初始化的全局变量、静态变量,还有常量数据(字符串常量)
- 代码区
- 用来存储程序的代码/指令。
C语言中的内存四区
数据类型本质分析
- C/C++编译器,为什么会引入数据类型这个概念?
- 为了在C/C++编译器中方便表达现实生活中的人事物。
- 数据类型和内存有关系吗?
- 数据类型的本质
- 数据类型可理解为创建变量的模具(模子),是固定内存大小的别名。
- 数据类型的作用:编译器预算对象(变量)分配的内存空间大小
- 数据类型的大小(sizeof)
- sizeof是操作符,不是函数;sizeof测量的实体大小为编译期间就已确定
- 数据类型别名(typedef)
- 数据类型可以理解为固定大小内存块的别名,请问数据类型可以起别名吗?
-
为int取个别名
typedef int u32; printf("u32:%d \n", sizeof(u32));
- 数据类型的封装(void)
- void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。
- 用法1:数据类型的封装
-
典型的如内存操作函数memcpy和memset的函数原型分别为
void * memcpy(void *dest, const void *src, size_t len); void * memset ( void * buffer, int c, size_t num );
-
- 用法2: void修饰函数返回值和参数,仅表示无。
- 如果函数没有返回值,那么应该将其声明为void型
-
如果函数没有参数,应该声明其参数为void
int function(void) {return 1;}
- void指针的意义
- C语言规定只有相同类型的指针才可以相互赋值
- void*指针作为左值用于“接收”任意类型的指针
-
void*指针作为右值赋值给其它指针时需要强制类型转换
int *p1 = NULL; char *p2 = (char *)malloc(sizoeof(char)*20);
- 不存在void类型的变量
- C语言没有定义void究竟是多大内存的别名
- 思考问题:
- 一维数组、二维数组有数据类型吗?int array[10]。
- 若有,数组类型又如何表达?又如定义?
- 数组类型,压死初学者的三座大山
- 数组类型
- 数组指针
- 数组类型和数组指针的关系
- C语言中,函数是可以看做一种数据类型吗?
- 函数这种数据类型,能再重定义吗?
- 一维数组、二维数组有数据类型吗?int array[10]。
变量的本质分析
- 本质是:(一段连续)内存空间的别名(是一个门牌号)
- 程序通过变量来申请和命名内存空间 int a = 0
- 通过变量名访问内存空间
- 修改变量有几种方法?
- 直接
- 间接。内存有地址编号,拿到地址编号也可以修改内存;于是横空出世了!(编程案例)
- 内存空间可以再取给别名吗?
- 数据类型和变量的关系
- 通过数据类型定义变量