本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、内管理之结构体
1.1 最简单的数据结构之数组
为什么要有数组: 因为内存中有好多个类型相同、意义相关的变量需要管理,这个时候就需要数组来管理。如果用单独的变量来管理就会显得特别的乱。
1.2 数组的优势和劣势
**优势:**数组简单,可以用下标法进行访问,可以随机访问。 **劣势:**1、数组的元素类型必须相同。2、数组的大小一旦确定不能再修改,而且数组的大小在定义的时候就必须给出。
1.3 结构体的由来
为什么要发明结构体:因为可以解决数组的缺陷,一个结构体里面可以定义多种类型的变量
struct student
{
int age;
char name[20];
char sex;
int height;
};
当然不一定任何情况下都要使用结构体,有的地方使用数组更加简单。
二、内存管理之栈
2.1 什么是栈
栈是一种数据结构,C语言中使用栈来保存局部变量。栈是被发明出来管理内存的。
2.2 栈的特点
栈的内存有限。所以栈很珍惜空间,怎么去珍惜呢,用了两个指针,一个指针叫base,指向栈内存空间的起始地址,而且他不会动。还有一个top指针,他是浮动的,当栈里面没有东西的时候吗,base和top指针都指向起始地址,当栈里面存放了一个东西的时候,top指针就会往后移动,指向这个东西后面的一个内存地址。
举个例子,我们在0和1里面存放两个数据过后,top指针就会指向2,就是1存放了后,下面就会指向2,如果0123里面存放了数据,就会指向4.
当然,如果从栈里面取出东西,你必须从top指针开始往下面开始取,不能从0开始往上面取,这就是栈的先进后出特性。与之相对应的就是队列,可以把他想象成左耳进右耳出这种,你先进就先出。
2.3 栈中的局部变量
我们再C语言定义一个局部变量的时候,编译器会在栈中分配一个段空间给这个变量用,并且把他和这个名字绑定起来。 然后栈指针的移动和内存分配是自动的,也就是申请空间和释放空间都是编译器去完成,不需要我们去写代码控制。
还是以这张图为例子,当之前的栈里面存放的数据出栈的时候,原本栈里面的空间是否会改变呢,答案是不会,如果没有去清零。那么栈里面的存放数据还是存放的那个数据,只不过top指针跳过了而已。比如,top指针从4指向3过后,4里面存放的还是4只不过编译器认为他是空的,top指针也不管他,所以这就是所说的栈是脏的的由来。因为出栈后,原来的数据还在里面,内存也已经被玷污了。 所以如果我们定义了一个变量而不给他一个值,那么这个变量的值就是随机的,因为你不知道这个变量的地址里面存放的原来的值是什么。
2.4 栈缺点
内存不灵活,因为栈的大小是定义的,如果定义太大的栈,那么我们用不了多少就会浪费。若果定义小的栈,那么就可能不够,容易溢出。所以为了解决这种问题,我们最好在写程序的时候不要定义太多的变量,也不要定义很大的变量(a[99999])这种。
三、内存管理之堆
3.1 什么是堆
堆也是一种内存管理方式。因为我我们有时候要的变量很大,有时候较小,所以才有了不同的管理方式,才有了栈、堆这种区分。 堆很大,因为很大啊,编译器管不过来,所以就很自由,随时申请,随时释放,堆也只管理你申请了的地址空间。(malloc和free来管理)
3.2堆的特点
内存大,一般的1需求容量都能够满足。 手动化,也就是需要我们自己去申请,去释放,编译器不会管的(如果你只申请不释放,那么这段内存的就不会回到堆里面,堆的内存就会减小,如果你多次进行这种操作,堆的内存也会变的很小,最后就会溢出,然后程序就出现问题,这就是内存泄漏)
通过malloc calloc realloc来申请空间,详细的可以去liunx查看man手册。 通过free来释放内存。 堆内存申请一定要确定大小,若果需要更改就只能通过realloc接口来更改。
3.3 堆的缺点
不够灵活,需要程序员自己去解决,如果我们水平不高,那么很容易就会导致出现问题。