在说明c语言内存管理之前,要知道什么是内存,内存我个人认为可以理解为带有标签的盒子,所谓的带标签的盒子就像我们住的寝室一样有门牌号,盒子内只能存储固定类型的数据或变量,就如男生寝室只能住男生一样。那么C语言中有多少种盒子呢?有静态存储区、动态存储区、内部寄存器区域。我们通常定义的变量如果没有特意说明类型默认为自动变量类型存储在动态存储区,eg:
int a;//其实省略了变量在内存的存储类型声明(auto)
static int b;//b为静态变量,只需初始化一次,下次使用时会接着
//上一次的值
静态变量、动态变量和寄存器变量又有什么区别和优势呢?**对于动态存储区变量通常用于存储临时值,动态变量的生命周期小于静态变量的生命周期,即作用域不同。**典型的例子就是在被调用函数中定义的变量,当函数被调用时才给函数内部变量分配内存空间,当函数调用结束后,变量内存被回收。对于静态变量而言它存在静态存储区,其生命周期比较长,从文件执行开始直到文件关闭静态变量一直存在。寄存器变量一般用到的次数比较少(实际并不是这样的),寄存器变量的执行速度是最快的,因为其直接存储在内部的寄存器中,但寄存器变量不能过多,否则cpu会超负荷工作,反而影响效率。所以只有当一个变量反复频繁被调用时才可以声明为寄存器变量。现在的一些编译器都自带优化功能,会自动将使用频繁的变量转化为寄存器变量。
计算机内部的内存空间是连续的,但我们想使用一块空间来表示有序数据时,我们首先会想到数组,但数组有一个致命的缺点就是分配的内存固定,这样有时会给编程者带来不必要的麻烦,分配太多会造成内存浪费,分配少怕不够用,这时我们可以借助链表或内存动态分配函数来做,在这里主要介绍一下动态内存分配。C语言自带了三个内存管理函数,包含在头文件stdlib.h中
1.malloc函数
调用形式为: ‘’‘int *p=(int *)malloc(size)’’’;size为要分配的内存的大小,malloc函数分配内存空间函数,当分配成功时返回分配的首地址(返回值为void类型),失败时返回零。
2.calloc函数
与malloc函数的功能相似也是 进行内存划分,但此函数可以一次划分m个相同大小的内存块。调用形式为:’’‘int *p=(int *)calloc(m,size)’’’;size为每一块内存所占用的内存大小,m表示有多少这样的内存块。
3.realloc函数
从新分配有malloc或calloc函数分配的内存空间。
‘’'realloc()原型: void *realloc(void mem_address, unsigned int newsize);’’’
此函数的意义就是将mem_address指向的内存从新分配为大小为newsize的新空间。
4.free函数
malloc和calloc函数所开辟的内存空间都是在堆中开辟的,所以运行后要使用函数来释放内存。调用形式为free§;//p为地址指针
#include "stdafx.h"
#include<stdlib.h>
#include<stdio.h>
void main()
{
int *p = (int*)malloc(4 * sizeof(int)),*pt=NULL;
int i = 0;
for (i = 0; i < 4; i++)
scanf_s("%d", p + i);
for (i = 0; i < 4; i++)
printf("%d\t",*( p + i));
printf("重新分配内存");
pt = (int*)realloc(p, 10*sizeof(int));
memcpy(pt, p ,4*sizeof(int));//将原数组里的数复制到新开辟的空间了
printf("重新分配内存后的元素");
for (i = 0; i < 10; i++)
printf("%d\t", *(pt + i));
free(p);
free(pt);
}
最后说一句堆和栈的区别,在栈中分配的空间程序执行后会自动回收,但是在堆中开辟的空间不会主动回收