为什么存在动态内存分配,动态内存函数(malloc函数,free函数,calloc函数,realloc函数)...

点击蓝字

659fca768323293312cca67da89ab1cd.png

关注我们

1.当前我们知道的内存的使用方法

5ed9c6eab079ef066f7320f1be817eea.png

2.为什么存在动态内存分配

如上我们已学的开辟空间的方式有两个特点:

  • 空间开辟的大小是固定的

  • 必须指定数组的长度

所以就产生了空间开大了浪费开小了不够用的问题,所以使用动态内存分配

3.动态内存函数

(1)malloc 和 free

a.malloc函数

d6bc2d54dbda1a2f013f771040176244.png

malloc函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。

  • 如果开辟成功,返回一个指向开辟好空间的指针

  • 如果开辟失败,返回一个NULL指针,因此malloc的返回值一定要做检查

b. free函数

9c846d05852b86146593e2b5268b8d0d.png

free函数用来释放动态开辟的内存

  • 如果参数p指向的空间不是动态开辟的(eg:数组),那free函数的行为是未定义的;

  • 如果参数p是NULL指针,则函数什么事都不用做;

c.举例说明malloc函数和free函数如何使用

  •  开辟10个整形大小的空间,并将0-9放入
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
  //向内存申请10个整形的空间
  int* p = (int*)malloc(10 * sizeof(int));
  //开辟空间失败,打印失败原因
  if (p == NULL)
  {
    //errno:Last error number
    printf("%s\n", strerror(errno));
  }
  //开辟空间成功,将0-9放入
  else
  {
    for (int i = 0; i < 10; i++)
    {
      *(p + i) = i;
    }
    for (int i = 0; i < 10; i++)
    {
      printf("%d ", *(p + i));
    }
  }
  //释放掉p指向的这段空间,但是指针p还是指向这段空间
  free(p);
  //防止野指针,需要将指针制空
  p = NULL;
  return 0;
}

输出:

b3481505932cf7ff7c02a32750fed941.png

  • 开辟空间失败,并打印开辟失败原因

 INT_MAX 整形最大–>可右键转到定义查看
bf142e10a94c8cadbc48dd079988ae96.png

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
  //向内存申请10个整形的空间
  int* p = (int*)malloc(INT_MAX);
  //开辟空间失败,打印失败原因
  if (p == NULL)
  {
    //errno:Last error number
    printf("%s\n", strerror(errno));
  }
  //开辟空间成功,将0-9放入
  else
  {
    for (int i = 0; i < 10; i++)
    {
      *(p + i) = i;
    }
    for (int i = 0; i < 10; i++)
    {
      printf("%d ", *(p + i));
    }
  }
  //释放掉p指向的这段空间,但是指针p还是指向这段空间
  free(p);
  //防止野指针,需要将指针制空
  p = NULL;
  return 0;
}

6143e5fbef42d07a9e74cd968315e3a5.png

(2)calloc

a. calloc函数

9539e6b47d15ed90ed0f7eb79c397d9d.png

  • calloc函数的功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0

  • calloc和malloc的区别在于calloc会在返回地址之前把申请的空间的每个字节初始化为0

b.举例说明calloc函数如何使用

  • 开辟10个整形大小的空间并初始化为0
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
  int* p = (int*)calloc(10, sizeof(int));
  if (p == NULL)
  {
    printf("%s\n", strerror(errno));
  }
  else
  {
    for (int i = 0; i < 10; i++)
    {
      printf("%d ", *(p + i));
    }
  }
  free(p);
  p = NULL;
  return 0;
}

467aed2c1b1367917170e1aa564b9f4d.png

37ac4960ce663b924ad283d855a513c9.png

(3)realloc

a. realloc函数

f55975d089bc3fb707ddbcd3ef144de5.png

  • p是要调整的内存地址

  • size是调整之后的大小

  • 返回值为调整之后的内存起始位置

b.realloc在调整内存空间存在的两种情况:

 情况1:原有空间之后有足够大的空间

如果p指向的空间之后有足够的内存空间可以追加,则直接追加,然后返回p

152fa90491998d5d22c66b54f34affc2.png

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
  int* p = (int*)malloc(20);
  if (p == NULL)
  {
    printf("%s\n", strerror(errno));
  }
  else
  {
    for (int i = 0; i < 5; i++)
    {
      *(p + i) = i;
    }
  }
  //得用一个新的变量来接受realloc函数的返回值
  //防止开辟失败返回NULL给p找不到之前的空间
  int*ptr = (int*)realloc(p,40);
  if (ptr != NULL)
  {
    p = ptr;
    for (int i = 5; i < 10; i++)
    {
      *(p + i) = i;
    }
    for (int i = 0; i < 10; i++)
    {
      printf("%d ", *(p + i));
    }
  }
  free(p);
  p = NULL;
  return 0;
}

f51ef24235249776f60c77650f836c06.png

c9e16b3d61556cd769a9961c8f653c2e.png

情况2:原有空间之后没有足够大的空间

如果p指向的空间之后没有足够大的内存空间可以追加,则realloc函数会重新找一块新的内存区域,开辟一块满足需求的空间,并把原来内存中的数据拷贝到新的空间,释放旧的内存空间,最后返回新开辟的内存空间地址

776291f27eb993fba501ba20e8053281.png

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
  int* p = (int*)malloc(20);
  if (p == NULL)
  {
    printf("%s\n", strerror(errno));
  }
  else
  {
    for (int i = 0; i < 5; i++)
    {
      *(p + i) = i;
    }
  }
  //得用一个新的变量来接受realloc函数的返回值
  //防止开辟失败返回NULL给p找不到之前的空间
  int*ptr = (int*)realloc(p,4000);
  if (ptr != NULL)
  {
    p = ptr;
    for (int i = 5; i < 10; i++)
    {
      *(p + i) = i;
    }
    for (int i = 0; i < 10; i++)
    {
      printf("%d ", *(p + i));
    }
  }
  free(p);
  p = NULL;
  return 0;
}

33f5d8379699531f695b1bb52df30834.png

773c5616b7601a327266da52a6f0ef1c.png

注意:得用一个新的变量来接受realloc函数的返回值,防止开辟失败返回NULL给p找不到之前的空间

 
 
 
 

7fd67ba02f2335dac9bb92301ef0cc85.gif

如果你年满18周岁以上,又觉得学【C语言】太难?想尝试其他编程语言,那么我推荐你学Python,现有价值499元Python零基础课程限时免费领取,限10个名额!
▲扫描二维码-免费领取

70047d1affd9f666aacdba3da98bee45.gif

戳“阅读原文”我们一起进步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值