(c语言进阶)动态内存管理

发布时间:2024年01月17日

一.为什么要有动态内存管理

二.malloc和free

malloc函数———动态申请内存

基础概念 :头文件<stdlib.h>

应用方法??

#include <stdio.h>
#include<stdlib.h>
int main()
{
	//开辟40个字节的内存空间,将空间首地址指向p
	int* p = (int*)malloc(40);
	//判断申请内存空间是否成功
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	//给开辟的空间赋值
	for (i = 0; i < 10; i++)
	{
		*(p + i) = i;
	}
	//输出内容
	for (i = 0; i < 10; i++)
	{
		printf("%d ",*(p+i));
	}
	return 0;
}

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(4000000000000000);
	//判断申请内存空间是否成功
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	//给开辟的空间赋值
	for (i = 0; i < 10; i++)
	{
		*(p + i) = i;
	}
	//输出内容
	for (i = 0; i < 10; i++)
	{
		printf("%d ",*(p+i));
	}
	return 0;
}

free函数——接收内存首地址,释放动态申请的内存。

基础概念:头文件:<stdlib.h>

应用?

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(40);
	//判断申请内存空间是否成功
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	//给开辟的空间赋值
	for (i = 0; i < 10; i++)
	{
		*(p + i) = i;
	}
	//输出内容
	for (i = 0; i < 10; i++)
	{
		printf("%d ",*(p+i));
	}
	//释放内存
	free(p);
	//为了避免p指向的空间无意义,成为野指针,将p赋值为空;
	p = NULL;
	return 0;
}

三.calloc和realloc

calloc函数=malloc+将申请的内存中每个字节初始化为0

基础概念

应用?

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)calloc(10,sizeof(int));
	//判断申请内存空间是否成功
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	//输出内容
	for (i = 0; i < 10; i++)
	{
		printf("%d ",*(p+i));
	}
	//释放内存
	free(p);
	//为了避免p指向的空间无意义,成为野指针,将p赋值为空;
	p = NULL;
	return 0;
}

realloc函数 ——动态调整动态内存大小

基础概念?

应用?

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)calloc(10,sizeof(int));
	//判断申请内存空间是否成功
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	//输出内容
	for (i = 0; i < 10; i++)
	{
		printf("%d ",*(p+i));
	}
	//内存不够,扩大到20个整形大小
	int* ptr=realloc(p, 20 * sizeof(int));
	//如果修改内存成功,则把新内存的首地址指向p
	if (ptr != NULL)
	{
		p = ptr;
	}
	//释放内存
	free(p);
	//为了避免p指向的空间无意义,成为野指针,将p赋值为空;
	p = NULL;
	return 0;
}

调整内存失败和成功后出现的结果?

?

?realloc也可以当做malloc来用

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)realloc(NULL,10*sizeof(int));
	//判断申请内存空间是否成功
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(p + i) = i;
	}
	//输出内容
	for (i = 0; i < 10; i++)
	{
		printf("%d ",*(p+i));
	}
	//释放内存
	free(p);
	//为了避免p指向的空间无意义,成为野指针,将p赋值为空;
	p = NULL;
	return 0;
}

四.常见的动态内存的错误

1.对NULL指针的解引用操作

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(40);
	//如果内存申请失败,则p有可能是空指针,空指针不可解引用
	*p = 20;
	free(p);
	return 0;
}

2.对动态开辟空间的越界访问

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i;
	for (i = 0; i <= 10; i++)//开辟了十个整形的大小,访问到第十一个时越界
	{
		*(p + i) = i;
	}
	free(p);
	p = NULL;
	return 0;
}

3.对非动态开辟内存使用free释放

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int a = 10;
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	p = &a;
	//此时p指向的不再是动态申请的内存
	free(p);
	//无法释放非动态申请的内存
	p = NULL;
	return 0;
}

4.使用free释放一块动态开辟内存的一部分

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	p++;
	//此时p指向的已经不是内存的首地址了,只能释放其中的一部分内存
	//报错
	free(p);
	p = NULL;
	return 0;
}

5.对同一块动态内存多次释放

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	free(p);
	//对同一块内存重复释放,对不存在的内存进行释放,报错
	free(p);
	p = NULL;
	return 0;
}

6.动态开辟内存忘记释放(内存泄露)

#include <stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	//申请的内存由于死循环永远无法释放,导致内存泄露
	while (1);
	free(p);
	p = NULL;
	return 0;
}
文章来源:https://blog.csdn.net/2301_79580018/article/details/135607409
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。