C风格的动态内存管理(malloc、calloc、realloc、free)以及总结free崩溃常见的几种情况

申请内存

void * malloc(int size); //申请大小为size字节的队内存,失败返回NULL

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

void show(int* arr, int n) {
	for (int i = 0; i < n; ++i) {
		printf("arr[%d] = %d ",i,arr[i]);
	}
	printf("\n");
}

int main(){
	int n = 10;

	int* arr = (int*)malloc(n * sizeof(int));
	show(arr,n);
	if (arr != NULL) {
		free(arr);
	}
}

申请内存,并将内存初始化为0

void * calloc (int len,int size); //申请len*size大小的空间,并且将这块内存初始化为0

void show(int* arr, int n) {
	for (int i = 0; i < n; ++i) {
		printf("arr[%d] = %d ",i,arr[i]);
	}
	printf("\n");
}

int main(){
	int n = 10;
	int* brr = (int*)calloc(n,sizeof(int));
	show(arr, n);
	free(brr);
}

将已有的堆内存空间扩容至指定大小

void * realloc (void *memblock , size_t size);//memblock旧地址,size新地址的内存大小,而不是新增的大小

int main(){
	int* crr = (int*)malloc(n * sizeof(int));
	printf("crr = %x\n",crr);
	crr = (int*)realloc(crr,90);
	printf("crr = %x\n", crr);
}

释放内存

void free(void *memblock); //释放指定内存的堆空间

int main(){
	int *p = (int*)malloc(100);
	free(p);
}

free()如何知道需要释放多大的内存空间?

在这里插入图片描述
也就是说,比如我们用malloc向系统申请了100字节堆内存,实际上malloc会多申请几个字节,用来记录当前内存的大小以及前后的其他内存块的信息,具体实现有兴趣的读者可以去看ptmalloc的实现,这里不深入讲解。这就是我们调用free()没有传递内存大小但是它还是知道释放多大内存的原因。

总结几点free()不当造成的崩溃的问题:

  1. 重复释放,将已经释放不属于自己的内存又释放一次,造成崩溃:
int *p1 = (int*)malloc(100);
free(p1);
free(p1);
  1. 数组越界,导致内存块头部或者尾部信息被修改
int k = 10;
int* p = (int*)malloc(k*sizeof(int));
for (int i = 0; i <= k; ++i) {
	p[i] = 0;
}
//最后一次循环将尾部信息的值改为0,释放时造成崩溃
free(p);
  1. 将堆内存的起始地址移动位置,如进行自增或者自减(++ --)
int k = 10;
int* p = (int*)malloc(k*sizeof(int));
for (int i = 0; i <= k; ++i) {
	*p = 0;
	p++;
}
//将堆内存起始地址修改,访问不到正确的堆头部或者尾部信息,导致内存释放出现问题
free(p);
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值