动态内存管理

本文介绍了C语言中的动态内存管理函数malloc、free、calloc和realloc的使用,包括它们的功能、注意事项和常见操作。此外,还详细讲解了柔性数组的概念、特点和优势,强调了其在内存管理上的灵活性和便利性。通过实例展示了如何使用这些函数和柔性数组进行内存操作。
摘要由CSDN通过智能技术生成

目录

动态内存函数的介绍

malloc

free

calloc

realloc


在没学习动态内存开辟的时候,我们最常用的开辟内存方法应该是如下吧。

int arr1[20];
char arr2[20];

但是以上方法有一些缺点,比如说:

1.它的大小是固定的,不能随着需求的变化而变化

2.它需要在程序运行起来的时候才知道内存空间是浪费了还是缺少了。

所以就引进了动态内存管理的概念。

动态内存函数的介绍

在c语言中为我们提供了两个函数 mallocfree 

malloc

void* malloc(size_t size)

这个函数会向内存的堆区中申请一块连续的内存并且返回这块空间的地址

1.函数开辟成功会返回开辟的地址。

2.函数开辟失败,会返回NULL.

3.函数的返回值类型是void*需要根据需求进行转换。

4.如果size=0,是否有意义取决于编译器。

free

void free(void *ptr)

free函数会回收被动态内存开辟的空间

如果ptr不是动态开辟的那么free的执行结果取决于编译器。

如果给ptr传入NULL那么free会什么也不做。

举个例子

int main()
{
    int n=0;
    scanf("%d",&n);
    char *ptr=(char *)malloc(n*sizeof(int));
    if(ptr==NULL)
      {

        perror(malloc);

      }
     else
     { 
        int i=0;
        for(i = 0 ; i < n; i++)
          { 
               ptr[i]=i;
               printf("%d",ptr[i]+1);
           }
      }
    free(ptr);
    ptr=NULL;
    return 0;

}

calloc

void *calloc(size_t num,size_t size)

他也是一个动态内存开辟函数,它的作用和malloc有一些不同,它会将开辟的空间默认制成‘0’,

开辟num个size大小的空间。

 realloc

realloc函数的出现让动态内存开辟有了灵魂,它会更加的灵活,realloc会在原来malloc或calloc函数开辟的那块空间上进行空间大小的增改。

Void * realloc(void *ptr,size_t num)

ptr是需要调整空间的地址,num是它新的大小,返回值为调整后的内存地址,realloc函数在调整的时候还会原来内存中的数据移动到新的内存里

在调用realloc函数的时候会出现两种情况,

1.再增加内存的时候内存原有空间足够大。

2.原空间没u的那么大的内存。

当发生第一种情况的时候,realloc会正常的开辟空间返回该控件的地址,当发生第二种情况的时候realloc函数会在堆区中寻找一块连续的足够大的内存,并且把原来存放的内容全部搬运到新的内存空间中,并且返回新的地址。

柔性数组 

struct s3
{
    int num;
    int arr[];
};

像arr这样,在结构体中的最后一个成员是未指定大小的数组就叫做柔性数组。

柔性数组的特点

1.柔性数组必须是一个结构体的最后一个成员.

2.结构体大小和柔性数组无关。

3.通过malloc,realloc等函数进行灵活使用,但是开辟的空间大小要大于结构体大小来满足柔性数组的空间使用。

柔性数组的使用:

struct s3
{
    int num;
    int arr[];
};
int main()
{
     struct s3* ptr=(struct s3*)malloc(sizeof(struct s3)+100*4);   
    ptr->num = 100;
    for(int i=0; i < 100; i++)
   {

    ptr->arr[i] = i + 1;
    
   }
    free(ptr);
    ptr = NULL;
    return 0;
}

柔性数组的优势:

1.方便释放内存,像完成上面的那个代码如果不用柔性数组的话就要这么写

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
struct s4
{

    int num;
    int* pc;
};
int main()
{
    struct s4* ptr1 = (struct s4*)malloc(sizeof(struct s4));
    ptr1->pc = (struct s4*)malloc(sizeof(int) * 100);
    int i = 0;
    for (i = 0; i < 100; i++)
    {
        ptr1->pc[i] = i + 1;
        printf("%d ", ptr1->pc[i]);

    }
    free(ptr1->pc);
    ptr1 = NULL;
    free(ptr1);
    ptr1 = NULL;
    return 0;
}

和之前的那个对比来看,这种写法会两次开辟空间,导致存放的数据空间不是连续的,内存访问速度会下降,再就是释放开辟的空间的时候要释放两次,并且应该分先后顺序。使用起来很麻烦,不是很方便,如果我们在函数中使用上面这种代码,那么然后用户调用free他们不会知道要结构体中的内容也要free。

这是本人学习记录的博客如果有错误欢迎提醒,谢谢你,耐心地看完。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值