c/c++动态内存分配 malloc() 、calloc()、realloc()

在c/c++中, malloc() 、calloc()、realloc()、free()都是与动态内存分配相关的函数(动态内存分配是在程序运行时在heap(堆)上进行)。四者都在头文件<stdlib.h>中进行定义。

本文先对malloc()和calloc()进行简单介绍,再对内存调整函数realloc()进行重点介绍,最后是示例程序。

一、malloc() 和 calloc() 主要区别:

1、原型

 void* malloc( size_t size );

size为分配内存的总大小。
例如,为 int[10] 分配内存:malloc( sizeof(int) * 10).

void* calloc( size_t numElements, size_t sizeOfElement);

sizeOfElement 为分配内存的单元大小,numElement 为个数。即numElement 个大小为sizeOfElement 的内存。
例如,为 int[10] 分配内存:calloc( sizeof(int), 10)。

2、分配内存是否初始化
malloc() 不进行初始化,calloc() 进行初始化。

二、malloc() 和 calloc()的相同点

1、返回
如果调用成功,函数malloc()和函数calloc()都将返回所分配的内存空间的首地址,否则返回空指针NULL。所以调用之后最好进行一下判断。

int* arrMalloc = (int*)malloc(sizeof(int) * 10);
if(!arrMalloc){
	printf("Allocation Failed!");
	exit(-1);
}
	
int* arrCalloc = (int*)calloc(sizeof(int), 10);
if(!arrCalloc){
	printf("Allocation Failed!");
	exit(-1);
}

2、free() 释放
二者都使用free() 进行内存释放。free之后将其置为NULL,避免成为野指针。

free(arrMalloc);
arrMalloc = NULL;

free(arrCalloc);
arrCalloc = NULL;

注意,动态内存分配之后一定要进行释放,不然会造成内存泄漏(Memory Leak)。 同时,对于已经释放过的内存不能再次释放,否则会报错。

三、realloc()

realloc,动态内存调整(reset allocation),即对已经(使用malloc() 和calloc())分配的动态内存空间进行大小上的更改。

原理:
先判断当前的指针是否有足够的连续空间,如果有,即:realloc的内存 ≤ 原来的内存 + 原来的内存后面还剩余内存,则扩大mem_address指向的地址空间大小,并且将mem_address返回(注意:此时原内存空间里面的内容不变,还是返回原来内存的地址,但是是释放过后重新返回的);
如果空间不够,realloc将申请新的内存,按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。

//函数原型
void* realloc(void* mem_address, unsigned int newsize);
//mem_address:指要向改变内存大小的动态内存的指针名
//newsize:新的内存大小。注意是“总大小”,即sizeof(dataType) * newsize

说明:

  1. 新的内存可大可小
    如果新的大小大于原内存大小,则新分配部分不会被初始化;如果新的大小小于原内存大小,可能会导致数据丢失。
  2. 返回值
    如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL;
    当需要扩展的大小(第二个参数)为0并且第一个参数不为NULL时,原内存变成“free”的了。此时也返回为NULL。
int* arrMalloc = (int*)malloc(sizeof(int) * 10);
free(arrMalloc); 
//即上下两个语句块等价
int* arrMalloc = (int*)malloc(sizeof(int) * 10);
realloc(arrMalloc, 0)
  1. 当内存不再使用时,应使用 free()函数将内存块释放。
  2. 如果 mem_address为 NULL,则realloc()和malloc()类似,分配一个大小为newsize的内存块,返回一个指向该内存块的指针。
int* arrRealloc = (int*)realloc(NULL, sizeof(int) * 10); //相当于(int*)malloc(sizeof(int) * 10)
int* newArray = (int*)realloc(arrRealloc, sizeof(int) * 20); //对内存大小进行更改
free(newArray); //释放内存
  1. realloc失败,即没有足够的空间可供扩展时,返回NULL,原来的内存大小不改变,不会被释放和移动。
  2. 传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的,当然也可以为空。

四、示例程序

//错误操作示例
#include<stdio.h>
#include<stdlib.h>

int main(){
	int* arrMalloc = (int*)malloc(sizeof(int) * 10);
	if(!arrMalloc){
		printf("Allocation Failed!");
		exit(-1);
	}
	printf("malloc分配返回地址:%d\n",arrMalloc);
	arrMalloc[0] = 1;
 	*(++arrMalloc) = 2;   //错误操作 
	printf("第0个元素值:%d\n",arrMalloc[0]);
	printf("第0个元素地址:%d\n",&arrMalloc[0]);
	printf("第1个元素地址:%d\n",&arrMalloc[1]);
	printf("操作过后arrMalloc地址:%d\n",arrMalloc);
	free(arrMalloc);
	arrMalloc = NULL;
	
	return 0;		
}  
	

运行结果:

malloc分配返回地址:11080672
第0个元素值:2
第0个元素地址:11080676
第1个元素地址:11080680
操作过后arrMalloc地址:11080676
Process exited after 3.019 seconds with return value 3221226356

*(++arrMalloc) 操作改变了arrMalloc的值,后面free的时候程序异常退出。所以要注意在程序中不能改变malloc分配的返回地址。

//简单完整示例程序
/**********************
Author:Ice
Description:The usage of malloc() and realloc()
Date:2020/2/3
**********************/

#include<stdio.h>
#include<stdlib.h>

int main(){
	int n;
	scanf("%d",&n);
	int* array = (int*)malloc(sizeof(int) * n); //使用malloc分配内存 
	if(!array){
		printf("Allocation Failed!");
		exit(-1);
	}
	
	int i;
	for( i = 0; i < n; i++){
		array[i] = i + 1;
		printf("%d ",array[i]); 
	}
	printf("\narray: %d\n", array);
	
	int increment = 10;
	int* newArray = (int*)realloc(array,(n + increment) * sizeof(int)); // 扩大内存,不用手动free(释放) array 
	if(!newArray){
		printf("Allocation Failed!");
		exit(-1);
	}
	
	for( i = n; i < n+increment; i++){
		newArray[i] = i + 1;
		printf("%d ",newArray[i]); 
	}
	printf("\nnewArray: %d\n", newArray);
	
	//打印出全部元素 
	for( i = 0; i < n + increment; i++){
		printf("%d ",newArray[i]); 
	}
	printf("\n");
	
	free(newArray); //记得释放内存 
	newArray = NULL; //避免newArray成为野指针
	 
	return 0; 
}	
	

运行结果:

7
1 2 3 4 5 6 7
array: 136160
8 9 10 11 12 13 14 15 16 17
newArray: 136160
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Process exited after 3.933 seconds with return value 0

参考资料:
百度百科-realloc函数

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值