【C语言高阶篇】成为编程高手必学内容,动态内存分配我不允许还有人不会!(下)

简介: 【C语言高阶篇】成为编程高手必学内容,动态内存分配我不允许还有人不会!(下)

💭 内存函数 free的错误使用

如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。

  • 这种行为是不被允许的,希望大家使用时注意!

📚 代码演示:

int main()
{
  int a = 10;
  int* p = &a;
  free(p);//err
  return 0;
}

📑 代码结果:

3️⃣ 动态内存函数 calloc

  ⛳️ C语言还提供了一个函数叫 calloccalloc 函数也用来动态内存分配。其实非常简单这个函数和 malloc 的功能是一样的,只不过会把申请的空间初始化为 0

函数原型如下:

void* calloc (size_t num, size_t size);
  • 函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
  • 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。

📜举个例子:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
  int arr[10] = { 0 };
  int* p = calloc(10,sizeof(arr[0]));
  //开辟失败
  if (p == NULL)
  {
    perror("calloc");
    return 1;
  }
  //开辟成功
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    printf("%d\n", p[i]);
  }
  free(p);
  p = NULL;
  return 0;
}

📑 代码结果:

  ⛳️ 这里就不给大家过多描述了,这个函数和malloc的使用大致一样!好的习惯是每次申请的动态空间在用完的时候都要释放掉!

4️⃣ 动态内存函数 realloc

  ⛳️有人会说不是动态内存可大可小嘛?想要多少空间就要多少,不想要了就可以缩小!前面的函数只能开辟和释放并不能控制大小啊?下面我们就给大家介绍介绍realloc函数它就完美的实现了这些功能。

  • 而想熟练的使用realloc函数就得知道
  • realloc开辟内存的三种情况

realloc 函数函数原型如下:

void* realloc (void* ptr, size_t size);

💭 内存函数 free的参数说明

realloc函数的出现让动态内存管理更加灵活:

void* realloc (void* ptr, size_t size);

  • ptr是要调整的内存地址
  • size调整之后新大小
  • 返回值为调整之后的内存起始位置。
  • 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 新 的空间。

📚 代码演示:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
  int arr[10] = { 0 };
  int* p = calloc(10,sizeof(arr[0]));
  //开辟失败
  if (p == NULL)
  {
    perror("calloc");
    return 1;
  }
  //开辟成功
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    printf("%d\n", p[i]);
  }
  //增加空间
  realloc(p, 80);
  free(p);
  p = NULL;
  return 0;
}

这就是realloc的用法当我们说开辟的空间只有40个大小不够用了。那么就可以用realloc去增加为80个字节大小!

💭 内存函数 free的3种使用情况

✅情况一

⛳️ 第一种情况就是后面的连续空间足够,我们我们就会在后给连续的新开辟40个字节使其增加为80个字节大小!

  • 下面给大家看看看内存分布情况图

📚 代码演示:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
  int arr[10] = { 0 };
  int* p = calloc(10,sizeof(arr[0]));
  //开辟失败
  if (p == NULL)
  {
    perror("calloc");
    return 1;
  }
  //开辟成功
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    printf("%d\n", p[i]);
  }
  //增加空间
  realloc(p, 80);
  free(p);
  p = NULL;
  return 0;

📑图片展示:

这就是第一种情况的内存分布,当后面的空间足够时后给连续的新开辟40个字节使其增加为80个字节大小

✅情况二

  ⛳️当我们想用reaclloc增加空间时,但是后面空间不够了就会重新开辟新空间并将原来空间的内容拷贝到新空间,并且将旧空间释放掉.

这里我们思考一个问题,realloc也会返回失败那么就会返回NULL空指针!

  • 本来我p指针变量还维护40个字节的大小结果你给一个空指针
  • 那么我不仅新空间没开辟,旧空间也丢了,

这样就会造成内存泄漏的问题,所以我们在这里就不敢用p接收我们的realoc返回值,需要进行代码改进!

📚 代码演示:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
  int arr[10] = { 0 };
  int* p = calloc(10,sizeof(arr[0]));
  //开辟失败
  if (p == NULL)
  {
    perror("calloc");
    return 1;
  }
  //开辟成功
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    printf("%d\n", p[i]);
  }
  //增加空间
  int* ptr = realloc(p, 80);
  if (ptr != NULL)
  {
    p = ptr;
    ptr=NULL;
  }
  else
  {
    perror("realloc");
  }
  free(p);
  p = NULL;
  return 0;
}

这样就可以避免我们上面说的错误了,如何 realloc 开辟失败我们就不接收空指针。

  • if判断完了之后再决定接不接收就完美解决问题

✅ realloc如何减少空间

  ⛳️ 这个不就更加简单了嘛?前面说了我们realloc函数可以动态开辟空间可大可小!那么使动态内存变小不就是更加简单了嘛?直接把内存改小不就行了.

  • 下面就来演示一下如何使动态内存变小

📚 代码演示:

#include <stdio.h>
#include <stdlib.h>
int  main()
{
  int arr[10] = { 0 };
  int* p = calloc(10,sizeof(arr[0]));
  //开辟失败
  if (p == NULL)
  {
    perror("calloc");
    return 1;
  }
  //减少空间
  int* ptr = realloc(p, 20);
  if (ptr != NULL)
  {
    p = ptr;
  }
  else
  {
    perror("realloc");
  }
  free(p);
  p = NULL;
  return 0;
}

📑 代码结果:

⛳️这里就可看到我们把malloc申请的动态空间40个字节,改变成了20个字节!

✈️ 总结

✅ 归纳:

好了以上就是关于动态内存分配函数 mallocfreecallocrealloc 4个动态内存分配函数的全部用法了!

  malloc的介绍和使用方法

  free的介绍和使用方法

  calloc和malloc的区别

  realloc语句使用的2种情况

☁️ 把这些内存函数掌握完,你就可以完美的使用动态内存分配了快去试试吧!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖

拜托拜托这个真的很重要!

你们的点赞就是博主更新最大的动力!

有问题可以评论或者私信呢秒回哦。


目录
相关文章
|
1天前
|
程序员 编译器 C语言
C语言----动态内存分配(malloc calloc relloc free)超全知识点
C语言----动态内存分配(malloc calloc relloc free)超全知识点
14 6
|
1天前
|
存储 Serverless C语言
每天一道C语言编程(结构体的运用):这是一年的第几天?
每天一道C语言编程(结构体的运用):这是一年的第几天?
6 0
|
1天前
|
C语言
每天一道C语言编程(递归:斐波那契数,母牛的故事)
每天一道C语言编程(递归:斐波那契数,母牛的故事)
5 0
|
1天前
|
C语言
每天一道C语言编程(2^k进制数)
每天一道C语言编程(2^k进制数)
5 0
|
1天前
|
C语言
每天一道C语言编程(数组操作)
每天一道C语言编程(数组操作)
5 0
|
1天前
|
C语言
每天一道C语言编程(数字转字母,字母转数字)
每天一道C语言编程(数字转字母,字母转数字)
5 0
|
1天前
|
C语言
每天一道C语言编程(求PI)
每天一道C语言编程(求PI)
5 0
|
1天前
|
C语言 C++
每天一道C语言编程:(去掉:双斜杠注释,去掉空格)
每天一道C语言编程:(去掉:双斜杠注释,去掉空格)
4 0
|
1天前
|
C语言
每天一道C语言编程:Hanoi双塔问题
每天一道C语言编程:Hanoi双塔问题
10 0
|
1天前
|
C语言
每天一道C语言编程:求N以内的素数(普通方法+优化方法)
每天一道C语言编程:求N以内的素数(普通方法+优化方法)
5 0