C语言动态内存分配与释放

来源:互联网 发布:白骑士大数据电话 编辑:程序博客网 时间:2024/05/16 05:22

内存静态存储区(static):全局变量、静态变量(static int a;)

内存动态存储区(栈stack):局部变量

内存自由存储区(堆heap):临时用数据

其中静态存储区、动态存储区的变量空间开辟和释放自动进行,不需要程序人员操作内存;

只有堆区需要手动开辟和释放空间:静态开辟——在编译时刻,数组的空间大小就开辟完成;

动态开辟——malloc、calloc、realloc;手动释放空间free


void *malloc(unsigned int size);   开辟size大小数目的字节空间

void *calloc(unsigned n,unsigned size);   开辟n个字节块大小为size的内存空间

void *realloc(void *p,unsigned int size);   第一次p指针开辟长度不够,重新选址开辟size大小数目的字节空间


malloc

#include<stdio.h>#include<stdlib.h>int main(){int n;printf("input n:>");scanf("%d",&n);int *p=(int *)malloc(sizeof(int)*n);   //申请开辟空间if(NULL==p){printf("malloc memory fail!\n");exit(1);   //检查malloc开辟空间是否成功,失败p无指向退出程序}for(int i=0;i<n;++i){p[i]=i+1;printf("%d",p[i]);}system("PAUSE");return 0;}



calloc

#include<stdio.h>#include<stdlib.h>int main(){int n;printf("input n:>");scanf("%d",&n);int *p=(int *)calloc(n,sizeof(int));   //申请开辟n块大小为sizeof(int)个字节的空间if(NULL==p){printf("malloc memory fail!\n");exit(1);   //检查malloc开辟空间是否成功,失败p无指向退出程序}for(int i=0;i<n;++i){p[i]=i+1;printf("%d",p[i]);}system("PAUSE");return 0;}

realloc

#include<stdio.h>#include<stdlib.h>void main(){int *p=(int *)malloc(sizeof(int)*5);if(NULL==p){printf("malloc memory fail!\n");exit(1);}for(int i=0;i<5;++i){p[i]=i+1;}//起初申请的5个空间不够用p=(int *)realloc(p,sizeof(int)*10);   //realloc对p所指的原始空间进行开辟,但开辟空间前后p所指的内存地址不一定一样//把原来的5个扩展为10个,用原来的指针p接收realloc的返回值,如果没有接收指针p,会丢失先前空间的值if(NULL==p){printf("malloc memory fail!\n");exit(1);}for(i=5;i<10;++i)   {p[i]=i+1;}for(i=0;i<10;++i){printf("%d",p[i]);}system("PAUSE");}

realloc对p所指的原始空间进行开辟,但开辟空间前后p所指的内存地址不一定一样
把原来的5个扩展为10个,用原来的指针p接收realloc的返回值,如果没有接收指针p,会丢失先前空间的值
第一次申请空间在内存里有个位置,第二次申请空间时,会检查内存里其后的空间大小是否满足申请大小:
如果满足,可以不修改第一次p的指向,连续地在其后开辟空间
如果不满足,要在内存中寻找满足大小的空间,如果找不到就开辟失败NULL,找到了就返回该空间的地址,并存放值




自定义函数模拟分析realloc过程,还原第一次被开辟空间被free释放过程

#include<stdio.h>#include<stdlib.h>#include<memory.h>//模拟realloc开辟空间过程自定义函数my_realloc,第一次被开辟空间free释放void* my_realloc(void *p,size_t size)   //size_t的类型在底层是无符号整型{void *new_p=malloc(size);if(NULL==new_p){printf("malloc memory fail!\n");exit(1);}memcpy(new_p,p,size);   //内存拷贝函数,将p指针空间的size个元素拷贝给new_p指针空间free(p);   //释放第一次开辟的空间p=new_p;   //把新开辟空间地址赋值给第一次开辟空间定义的指针变量preturn p;}void main(){int *p=(int *)malloc(sizeof(int)*5);if(NULL==p){printf("malloc memory fail!\n");exit(1);}for(int i=0;i<5;++i){p[i]=i+1;}//起初申请的5个空间不够用,自定义my_realloc重新拷贝函数p=(int *)my_realloc(p,sizeof(int)*10);if(NULL==p){printf("malloc memory fail!\n");exit(1);}for(i=5;i<10;++i)   {p[i]=i+1;}for(i=0;i<10;++i){printf("%d",p[i]);}system("PAUSE");}


void类型指针是“指向空类型”或“不指向确定的类型”的数据

注意melloc、alloc、realloc函数原本返回值类型就是void型指针,所以要想给真实类型指针赋值,需要进行强制类型转换

#include<stdio.h>#include<stdlib.h>void main(){int a=10;double d=12.34;int *p=(int *)&d;   //强制指针类型转换才能进行赋值void *pv=&a;   //void泛型指针pv=&d;   //void型指针可以接收一切类型地址//但由于其类型未知无法为其开辟空间,不能进行pv++操作int *pa=(int *)pv;   //也不能用void型指针给确定类型指针赋值//void类型不能转换成真实类型,需要强制类型转换才能赋值}





原创粉丝点击