C语言:动态内存分配

 

动态内存函数:malloc   free   calloc   realloc   //<stdlib.h>

  • malloc
    • void* malloc(size_t size)
    • 开辟成功返回开辟好空间的地址,失败返回 NULL
  • free
    • 释放动态开辟空间,该空间必须是动态开辟的
    • 	//当空间不在使用,则释放空间,	//p虽然被释放,但地址没变,还是可以找到该空间
      	free(p);
      	//断开P和该地址的联系
      	p = NULL;
      #include <stdio.h>
      #include <string.h>
      #include <stdlib.h>
      #include <errno.h>
      
      int main()
      {
      	//像内存申请10个int 空间
      	int* p = (int*)malloc(10 * sizeof(int));
      	if (p == NULL)
      	{
      		//打印失败原因
      		printf("%s\n", strerror(errno));
      	}
      	else
      	{
      		//开辟成功
      		int i = 0;
      		for (i = 0; i < 10; i++)
      		{
      			*(p + i) = i;
      			printf("%d ", *(p + i));
      		}
      	}
      	//当空间不在使用,则释放空间,	//p虽然被释放,但地址没变,还是可以找到该空间
      	free(p);
      	//断开P和该地址的联系
      	p = NULL;
      	return 0;
      }

       

  • calloc
    • void* calloc ( size_t num, size_t size)

      函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为 0,跟 malloc 区别就是是否初始化

    • 	int* p = (int*)calloc(10,10 * sizeof(int));
      	if (p == NULL)
      	{
      		//打印失败原因
      		printf("%s\n", strerror(errno));
      	}
      	else
      	{
      		int i = 0;
      		for (i = 0; i < 10; i++)
      		{
      			printf("%d ", *(p + i));
      		}
      	}
      	free(p);
      	p = NULL;

       

  • realloc
    • 调整动态开辟空间的大小
    • void *realloc(void *ptr, size_t size)
      
      //ptr -- 指针指向一个要重新分配内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针。
      
      size -- 内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针

       

 realloc使用的注意事项:

  1. 如果 P 指向的空间之后有足够的空间可以追加,则直接追加,返回 P
  2. 如果没有足够的空间可以追加,则 realloc 会重新找一块满足需求的内存空间开辟,并且把原来内存中的数据拷贝过来,释放旧的内存空间,最后返回 新的地址
int* p = (int*)malloc(20);
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	else
	{
		int i = 0;
		for (i = 0; i < 5; i++)
		{
			*(p + i) = i;
		}
	}
	int* ptr = (int*)realloc(p, 40);
	int i = 0;
	if (ptr != NULL)
	{
		p = ptr;
		for (i = 0; i < 10; i++)
		{
			printf("%d ", *(p + i));
		}
	}
	else
	{
		;
	}
	free(p);
	p = NULL;

 

动态内存分配常见错误:

  1. 对空指针的解引用
    1. 解决方法:动态内存分配后,一定要对返回值进行判断 (?==NULL)
  2. 对动态开辟内存的越界访问
  3. 对非动态开辟的空间 free
  4. 使用 free 释放动态开辟内存的一部分
  5. 对同一块动态内存的多次释放
    1. 解决方法  free(p) 后,将 p 置为 NULL 
  6. 对动态开辟的空间忘记释放(会造成内存泄漏)

 

柔性数组:结构体中的最后一个元素允许是未知大小的数组,这就叫 柔性数组 成员

Struct S
{
    int n;
    char c;
    int arr[0];//柔性数组成员,也可以写成 arr[]
}


struct s* p = (struct s*)malloc(sizeof(struct S) + 10 * sizeof(int));


free(p);
p=NULL;

柔性数组前,至少有一个其他成员

sizeof 返回的这种结构大小不包括柔性数组的内存

包含柔性数组成员的结构用 malloc 进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值