C语言--关于动态内存管理--malloc--free--realloc--calloc--理解

动态内存管理

关于动态内存管理,重点就是!!动态!!,这两个字,我们在之前学习了简单的内存开辟

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的用法,点击此处

上一篇:Roarctf 几道pwn 复现


下一篇:Mary_Morton