【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种情况

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

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

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

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

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

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


目录
相关文章
|
2月前
|
存储 编译器 程序员
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
在C语言中,内存布局是程序运行时非常重要的概念。内存布局直接影响程序的性能、稳定性和安全性。理解C程序的内存布局,有助于编写更高效和可靠的代码。本文将详细介绍C程序的内存布局,包括代码段、数据段、堆、栈等部分,并提供相关的示例和应用。
74 5
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
|
2月前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
77 8
|
2月前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
102 6
|
3月前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
88 6
|
3月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
267 13
|
3月前
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
100 4
|
3月前
|
大数据 C语言
C 语言动态内存分配 —— 灵活掌控内存资源
C语言动态内存分配使程序在运行时灵活管理内存资源,通过malloc、calloc、realloc和free等函数实现内存的申请与释放,提高内存使用效率,适应不同应用场景需求。
|
3月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
3月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
99 1
|
3月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。

热门文章

最新文章