C语言动态内存分配

十、动态内存分配

动态内存是在堆区开辟空间

 10.1 malloc函数

格式:void* malloc(size_t size)

size是开辟空间的字节数,malloc的返回值是一个空指针,是开辟空间的首字节地址

这里开辟了一个10个int大小的空间,并把首字节地址赋给p

void main()
{
	int* p = (int*)malloc(10 * sizeof(int));
	
	if (p==NULL)
	{
		printf("%s", strerror(errno));
	}
	else
	{
		for (int i = 0; i < 10; i++)
		{
			*(p+i) = i + 1;
		}
		for (int i = 0; i < 10; i++)
		{
			printf("%d\n", *(p+i));
		}
		
	}
}

打印结果:

1
2
3
4
5
6
7
8
9
10

10.2 free函数

free函数释放和回收动态内存,一般malloc和free函数要搭配使用 

格式:void free(void* ptr)

 注意:使用free()后只是释放了参数指针ptr指向的动态内存空间,但ptr仍然指向那片内存的首地址,仍然有通过ptr调用空间的可能。所以再free函数之后,还要将ptr变成空指针

free(p);            //p是指向先前开辟的内存空间首地址
p=NULL;

10.3 calloc

calloc函数同样用于开辟动态内存空间,且会将开辟的空间自动初始化为0

格式:void* calloc (size_t num, size_t size);

num是要开辟的元素的个数,size是一个元素占的字节,返回开辟空间的首字节地址

void main()
{

	int* p = calloc(10, sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		*(p + i) = i;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d\n", *(p + i));
	}
	free(p);
	p = NULL;
	
}

10.4 relalloc

relalloc用于扩大先前用malloc、calloc函数开辟好的动态内存

格式:void* realloc (void* ptr, size_t size);

ptr是先前已有的用malloc或者calloc函数开辟的空间的指针,size是重新定义空间的大小,返回值是重新开辟的空间的指针

使用realloc函数需要注意,realloc在追加空间时有三种情况:

1.先前开辟的动态内存空间后面还有足够的空间进行追加,或者说所需追加的空间小于先前开辟的动态内存空间后方闲置空间,那么此时relalloc函数将直接在后方追加开辟的空间,返回的地址就是先前开辟的空间的地址,即返回的地址=参数指针ptr

2.先前开辟的动态内存空间后方闲置的空间<追加的空间,此时realloc函数会重新找一片足够大的内存空间,并把原有的内容拷贝过去,此时返回的地址则不再是之前动态内存空间的地址,即返回指针 !=参数指针ptr。所以用realloc函数时最好将返回指针重新赋给ptr或者新的指针

p = realloc(p, 15*sizeof(int));

3.当参数size太大,realloc找不到开辟空间时会返回NULL,此时产生一个问题,如果像上面一行代码p = realloc(p, 40000*sizeof(int))将返回地址赋给原来的指针,那么执行完这行代码后p=NULL,就导致原来开辟的那块内存空间丢失了,再也无法通过p找到。所以用realloc函数时最好用下面这种代码

	int* ptr = NULL;
	ptr = realloc(p, 15*sizeof(int));
	if (ptr != NULL)
	{
		p = ptr;
	}

先用一个新的指针接收返回的地址,如果返回的不是空指针再赋给p

补充;可用realloc实现malloc的功能

int *p=realloc(NULL,40);//等价malloc(40)

 

10.5动态内存常见错误

10.5.1 对NULL指针解引用

10.5.2 动态内粗越界访问

10.5.3用free函数对非动态内存释放

10.5.4free函数释放部分动态内存

10.5.5free函数多次释放同一块动态内存

free(p);
p=NULL

 10.5.6未释放动态开辟空间(内存泄漏)

10.6 关于动态内存的面试题

 

 

非法访问内存 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值