动态内存管理
关于动态内存管理,重点就是!!动态!!,这两个字,我们在之前学习了简单的内存开辟
int arr[10]={0}; //开辟了40个静态字节
char A='d'; //开辟了一个字节
这都是我们之前所用到的,也是最简单的.但是它所开辟的字节数是固定的,不能随着内部数据增加,而是这个内存变大,在会解决一些比较大的项目的时候就出先了比较大的BUG,所以我们就需要用到这里要说的动态内存,我们这里有四个函数需要进行理解,如下:
malloc函数
向内存申请一段连续的动态内存,并且返回对应的指针,就是malloc 函数
void* malloc(size_t size);
直接例题理解:
void func1(){
//这里的INT_MAX是系统自身的一个宏定义,当申请的内存过大无法申请出来时,会返回NULL
int* p = (int*)malloc(INT_MAX / 4); //将malloc 申请的内存转成整型的动态内存,并赋给p指针
*p = 100; //赋值
printf("%p %d\n",p,*p); //打印
free(p); //!!!!!!!!!!内存释放
}
就像我下面说的,在申请了动态内存后,必须进行内存释放,不然就会造成内存泄漏,在程序员的生涯中是一个重大的失误,都有可能被扣工资!!!
free函数
因为内存是一定的,总会有用完的时候,所以我们在向内存用malloc函数申请内存使用完毕后,我们就要用free函数对申请的内存进行释放,从而让内存可以多次利用,取之不尽,用之不完,多次循环.
void free (void* ptr);
同上例题理解:
void func2(){
//p相当于一个动态的数组,只不过是通过malloc申请的
int* p = (int*)malloc(10 * sizeof(int)); //申请到10个字节大小和int一样的动态内存并将指针指向P
for (int i = 0; i <= 10; i++){
printf("%d\n",p[i]); //简单循环打印动态数组中的值
}
free(p); //!!!!!!!!释放
}
free操作在上面那个例题已经很明显的体现了出来,一定要进行内存释放!!!
realloc函数
这是一个比较重要的函数,体现了动态内存的动态性,它是在我们发现申请的内存过小的时候,直接运用这个函数,增大内存,可以更好地存储更多的数据.
void* calloc(size_t num,size_t size);
int main()
{
int *ptr = malloc(100); //开辟动态内存
if(ptr != NULL) //进行一系列的操作
{
//业务处理
}
else
{
}
//扩展容量
//1.
ptr = realloc(ptr, 1000); //这样直接开辟内存的格式是对的,但是在此段内存后面
//有足够1000的连续内存吗?很显然答案是不确定的,所以我们需要开辟一段新的内存将值传进去就好了
//所以我们有了下面的方法:
//2.
int*p = NULL;
p = realloc(ptr, 1000); //开辟新的内存,并将原来的指针中的值赋予
if(p != NULL) //赋予值
{
ptr = p;
}
free(ptr); //因为这里运用了新的指针新的空间,所以,我们要将原来的空间进行释放!!!!
return 0;
}
calloc函数
和malloc 的函数效果一致,只不过它的独特之处就是将所申请的内存进行全0初始化,在这里我们要清楚,在申请内存的时候全0初始化并不是最好的,在我们需要的时候完全可以增加一个命令行来初始化全0,并不麻烦,反而在刚一开始的时候对所申请的内存全0初始化会使代码变得复杂,所以它也不常用,memset函数也可以进行全0初始化!!
void* realloc(void* ptr,size_t size);
int main(){
int *p=calloc(10,sizeof(int)); //创建一个为全0的10*4字节的动态数组并赋值给P指针
if(NULL!=p){ //简单利用
//使用空间
}
//这里就是检测看是否全为0的操作
for (int i = 0; i < 10; i++){
printf("%d\t",p[i]);
}
free(p); //空间释放
p=NULL; //使用后的指针也要进行NULL处理
return 0;
}
总结:这篇主要就是理解动态两个字,只要你理解了,再将对应的四个函数灵活运用就可以了.下面贴了两个与这篇内容相关的,大家可以看一下.还是多敲代码!!大家一起加油!!
关于size_t的用法,点击此处
关于memset的用法,点击此处