C语言进阶学习日志:动态内存分配

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: C语言进阶学习日志:动态内存分配

malloc函数:

这是在堆区上开辟空间的函数 头文件为stdlib.h

81cfae54437748b686cfa209001210da.png

根据这张图片我们可以知道 malloc函数的参数是 字节  返回类型是void * 类型 还知道这个函数开辟空间返回的是这块空间的起始地址 如果开辟空间失败 就会返回 NULL指针

所以我们在使用这个函数的时候如果没有对这个函数的返回类型做检查 那么编译器会报错 说malloc函数返回的指针可能为空 虽说这个错误是无关紧要的 没有这个错误程序也能运行 但谁也说不准它会不会开辟失败 所以还是严谨点要好

如果说参数 为0 那么malloc的行为是不确定的 这个的看编译器怎么办

int main()
{
  int* p = (int*)malloc(5*sizeof(int));//这里强转是因为malloc返回的是void* 虽然有些编译器
  if(p==NULL)                          //不转也行 但还是转一下会好一点
 {
   printf("%s",strerror(errno));
   //strerror字符串函数 在我之前的文章 字符串操作函数
 }
 free(p);
}

大家注意到我上面的代码 里面的free函数了吗 这个free函数是为了 将我们向内存申请的空间还回去 最后我们再来说这个


calloc函数:

这个和malloc函数相差不大 唯一的不同就是 这个函数开辟空间后并把这份空间的内容初始

33b2c6e7730b489aae0e13a5d147e8d1.png

#include <stdio.h>
#include <stdlib.h>
int main()
{
  int* p=(int*)calloc(5,sizeof(int));
  for(int i=0;i<5;i++)
  {
     printf("%d ",p[i]);   //打印出来的答案肯定是0 0 0 0 0
  }
}

所以calloc函数就没什么好说的了


realloc函数:

这个函数可用来调节我们开辟了的空间大小 也可以自己开辟一段空间

68038fafc10f401589553ffea7f22404.png

 通过这张图我们可以知道 它的第一个参数是malloc calloc realloc所开辟空间的首地址 ,但是如果你传进去的参数是NULL话  那么realloc函数的作用和malloc函数的作用是一样的


我们知道realloc函数也会返回一个空间的地址 那我们返回的地址应该放在哪里呢 ?是放在被重新分配大小的空间呢? 还是一份新的空间呢?

fd3099a02d8d40f688b4e9d1cb8d6cb5.gif

这个是第一种情况 我们开辟的空间后面有足够的空间  就直接在后面开辟空间返回的地址与之前相同 如果开辟失败返回NULL 

8d62a7d094224a1fabb3c082b471d6e4.gif

 这个是第二种情况后面的空间不足  则realloc会开辟一块新的空间  并把原来空间的数据拷进去同时把原来的空间释放掉 返回新空间的首地址 一样的开辟失败 还是会返回NULL


所以综合以上的两种情况我们平常在开辟空间的时候要注意开辟空间返回地址的检查 vs编译器就会这样 如果你没有对它检查就会报错  所以说这个看个人习惯  毕竟开辟失败的概率较小


free函数:

c10bd2f896bc43fc9953476f04f93a22.png


free函数是将 我们申请的空间还回去(释放掉)

有个要注意的点是 看下面的代码:>

#include <stdio.h>
int main()
{
    int* p=(int*)malloc(10*sizeof(int));//开辟十个int空间
    for(int i=0;i<5;i++)
    {
        *p=i;
        p++;
    }
    free(p);
}


大家觉得这里的 free 能把开辟的空间 free 掉嘛?

当然答案是肯定不能的 这串代码中我们开辟的空间返回的首地址放在p里面  在后面的for循环中 我们对前面五个空间 赋值 1 2 3 4 5 这个时候p指向第六个空间

这个时候是不能free掉的  我们开辟的空间是不能够free一部分的 所以我们开辟的空间返回的地址是一定要记住的

还有几个要注意的点:

① free不能free两遍

② 不能free不是动态内存的值

③ 动态开辟的内存要记得 free 掉 不然会造成内存泄漏

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
35 3
|
7天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
49 12
|
4天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
1月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
68 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
28天前
|
C语言
【c语言】动态内存管理
本文介绍了C语言中的动态内存管理,包括其必要性及相关的四个函数:`malloc`、``calloc``、`realloc`和`free`。`malloc`用于申请内存,`calloc`申请并初始化内存,`realloc`调整内存大小,`free`释放内存。文章还列举了常见的动态内存管理错误,如空指针解引用、越界访问、错误释放等,并提供了示例代码帮助理解。
38 3
|
1月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
56 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
1月前
|
编译器 程序员 C语言
深入C语言:动态内存管理魔法
深入C语言:动态内存管理魔法
|
1月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
30天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
25 0
|
1月前
|
C语言
保姆级教学 - C语言 之 动态内存管理
保姆级教学 - C语言 之 动态内存管理
20 0
下一篇
无影云桌面