C 内存管理

C 语言为内存的分配和管理提供了几个函数。这些函数可以在 <stdlib.h> 头文件中找到。

在 C 语言中,内存是通过指针变量来管理的。指针是一个变量,它存储了一个内存地址,这个内存地址可以指向任何数据类型的变量,包括整数、浮点数、字符和数组等。C 语言提供了一些函数和运算符,使得程序员可以对内存进行操作,包括分配、释放、移动和复制等。

序号函数和描述
1void calloc(int num, int size);在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 numsize 个字节长度的内存空间,并且每个字节的值都是 0。
2void free(void *address);该函数释放 address 所指向的内存块,释放的是动态分配的内存空间。
3void *malloc(int num);在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。
4void *realloc(void *address, int newsize);该函数重新分配内存,把内存扩展到 newsize。

注意:void * 类型表示未确定类型的指针。C、C++ 规定 void * 类型可以通过类型转换强制转换为任何其它类型的指针。

动态分配内存

编程时,如果您预先知道数组的大小,那么定义数组时就比较容易。例如,一个存储人名的数组,它最多容纳 100 个字符,所以您可以定义数组,如下所示:

char name[100];

但是,如果您预先不知道需要存储的文本长度,例如您想存储有关一个主题的详细描述。在这里,我们需要定义一个指针,该指针指向未定义所需内存大小的字符,后续再根据需求来分配内存,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{char name[100];char *description;strcpy(name, "Zara Ali");/* 动态分配内存 */description = (char *)malloc( 200 * sizeof(char) );if( description == NULL ){fprintf(stderr, "Error - unable to allocate required memory\n");}else{strcpy( description, "Zara ali a DPS student in class 10th");}printf("Name = %s\n", name );printf("Description: %s\n", description );
}

当上面的代码被编译和执行时,它会产生下列结果:

Name = Zara Ali
Description: Zara ali a DPS student in class 10th

上面的程序也可以使用 calloc() 来编写,只需要把 malloc 替换为 calloc 即可,如下所示:

calloc(200, sizeof(char));

当动态分配内存时,您有完全控制权,可以传递任何大小的值。而那些预先定义了大小的数组,一旦定义则无法改变大小。

重新调整内存的大小和释放内存

当程序退出时,操作系统会自动释放所有分配给程序的内存,但是,建议您在不需要内存时,都应该调用函数 free() 来释放内存。

或者,您可以通过调用函数 realloc() 来增加或减少已分配的内存块的大小。让我们使用 realloc() 和 free() 函数,再次查看上面的实例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{char name[100];char *description;strcpy(name, "Zara Ali");/* 动态分配内存 */description = (char *)malloc( 30 * sizeof(char) );if( description == NULL ){fprintf(stderr, "Error - unable to allocate required memory\n");}else{strcpy( description, "Zara ali a DPS student.");}/* 假设您想要存储更大的描述信息 */description = (char *) realloc( description, 100 * sizeof(char) );if( description == NULL ){fprintf(stderr, "Error - unable to allocate required memory\n");}else{strcat( description, "She is in class 10th");}printf("Name = %s\n", name );printf("Description: %s\n", description );/* 使用 free() 函数释放内存 */free(description);
}

当上面的代码被编译和执行时,它会产生下列结果:

Name = Zara Ali
Description: Zara ali a DPS student.She is in class 10th

您可以尝试一下不重新分配额外的内存,strcat() 函数会生成一个错误,因为存储 description 时可用的内存不足。

C 语言中常用的内存管理函数和运算符

  • malloc() 函数:用于动态分配内存。它接受一个参数,即需要分配的内存大小(以字节为单位),并返回一个指向分配内存的指针。

  • free() 函数:用于释放先前分配的内存。它接受一个指向要释放内存的指针作为参数,并将该内存标记为未使用状态。

  • calloc() 函数:用于动态分配内存,并将其初始化为零。它接受两个参数,即需要分配的内存块数和每个内存块的大小(以字节为单位),并返回一个指向分配内存的指针。

  • realloc() 函数:用于重新分配内存。它接受两个参数,即一个先前分配的指针和一个新的内存大小,然后尝试重新调整先前分配的内存块的大小。如果调整成功,它将返回一个指向重新分配内存的指针,否则返回一个空指针。

  • sizeof 运算符:用于获取数据类型或变量的大小(以字节为单位)。

  • 指针运算符:用于获取指针所指向的内存地址或变量的值。

  • & 运算符:用于获取变量的内存地址。

  • * 运算符:用于获取指针所指向的变量的值。

  • -> 运算符:用于指针访问结构体成员,语法为 pointer->member,等价于 (*pointer).member。

  • memcpy() 函数:用于从源内存区域复制数据到目标内存区域。它接受三个参数,即目标内存区域的指针、源内存区域的指针和要复制的数据大小(以字节为单位)。

  • memmove() 函数:类似于 memcpy() 函数,但它可以处理重叠的内存区域。它接受三个参数,即目标内存区域的指针、源内存区域的指针和要复制的数据大小(以字节为单位)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/820759.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DBA面试总结(Oracle篇)

一、备份恢复 1. RMAN备份是一种用于备份和恢复数据库文件归档日志和控制文件的工具软件&#xff0c;主要执行的是物理备份&#xff0c;可以执行完全或不完全的数据库恢复。既能支持热备&#xff0c;在归档模式下&#xff0c;RMAN可以执行在线备份。在非归档模式下&#xff0c…

OpenHarmony轻量系统开发【7】驱动之I2C显示OLED屏幕

7.1实验效果 Hispark WiFi开发套件又提供一个oled屏幕&#xff0c;但是鸿蒙源码中没有这个屏幕的驱动&#xff0c;我们需要自己去移植。 以下是移植效果&#xff1a; 接口&#xff1a;I2C 使用引脚&#xff1a;HI_IO_NAME_GPIO_13 、 HI_IO_NAME_GPIO_14 7.2代码 这里我直…

Java动态getter/setter

前言 个人日常工作中的开发经验总结 通过反射动态获取实体类getter 首先&#xff0c;构造getter方法的名字&#xff0c;然后通过getMethod()方法从Database类中获取该方法的引用。接着&#xff0c;使用invoke()方法来调用该方法&#xff0c;从而获取属性的值。在调用getMeth…

供应链金融机器学习建模实战

随着全球贸易的不断发展和供应链的日益复杂化&#xff0c;供应链金融作为一种新型金融工具&#xff0c;正逐渐受到企业和金融机构的关注和重视。供应链金融是指通过金融手段来优化和改进供应链中的资金流动和货物流动&#xff0c;以实现企业间的合作共赢。 供应链金融的核心是将…

Java的自定义线程池

Java的自定义线程池 自定义线程池的原因 在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供&#xff0c;不允许在应用中自行显示的创建线程&#xff0c;这样一方面使线程的创建更加规范&#xff0c;可以合理控制开辟线程的数量&#xff1b;另一方面线程的细节管理…

docker容器内的进程启动监控,容器进程所在的PID namespce

在容器内启动进程 docker exec -it 9c6b0b0509da /bin/bash cd /home ./testapp 主机上的监控程序同样可以监控到 13022 /home/testapp !!!!!发现异常进程:testapp, exePath:/home/testapp GetExePath()函数返回的值是/home/testapp &#xff0c;即&#xff1a;进程执行文件所…

不能在子类的初始化列表中初始化父类的成员

不能在子类的初始化列表中初始化父类的成员 错误示例代码 class A { protected:int n_; };class B : public A { public:B() : n_(0){} };编译报错如下&#xff1a; error: class ‘B’ does not have any field named ‘n_’前置知识 继承情况下的初始化顺序 子类对象的构…

FFmpeg: 自实现ijkplayer播放器--08视频解码线程设计

文章目录 视频解码解码流程视频解码线程音频解码线程数据帧队列类型定义数据帧队列api视频解码 视频解码,读取数据包(packet),生成数据帧(frame),放入数据帧队列,用来输出音频和视频 解码流程 stream_component_open: 分配解码器上下文 avcodec_alloc_context3将码…

高频九问:产品经理面试题解析

01 ▼ 需求评审时研发说需求实现不了怎么办&#xff1f; 1.站在技术的角度&#xff0c;了解无法实现的原因 2.看有哪些可以替代的方案 3.评估替代方案对项目本身的影响&#xff0c;如延迟&#xff0c;如若在可接受范围内&#xff0c;适当的妥协 02 ▼ 是否了解我们公司&a…

Flume配置案例@Source:文件,Channel+Sink:Kafka

Source&#xff1a;某个目录下所有文件 Channel&#xff1a;Kafka Sink&#xff1a;Kafka 【Source和Channel的选择】 1&#xff09;TailDirSource TailDirSource相比ExecSource、SpoolingDirectorySource的优势。 TailDirSource&#xff1a;断点续传、多目录。Flume1.6以前…

大模型微调技术概览解读(chatGLM-6B)

目录 一些比较流行的PEFT方案 Prompt Tuning Prefix Tuning LoRA QLoRA 引用链接 参考文档&#xff1a;通俗解读大模型微调(Fine Tuning) - 知乎 从参数规模的角度&#xff0c;大模型的微调分成两条技术路线&#xff1a; 一条是对全量的参数&#xff0c;进行全量的训练…

【从零开始手搓12306项目】五、如何保证不超卖、不少卖、还能承受极高的并发?

逻辑设计&模型实现 余票查询&#xff1a;记录站站余票 座位购买&#xff1a;记录座位销售详情&#xff08;将卖票变成01二进制数的计算&#xff09; 使用事务保证原子性

VMware设置静态ip:以Centos7为例

1、获取网段&#xff0c;子网掩码和网关 到此获取到的信息&#xff1a; 网段&#xff1a;192.168.204.128 ~ 192.168.204.254 子网掩码&#xff1a;255.255.255.0 网关IP&#xff1a;192.168.204.2 2、修改Centos系统的网络配置 使用命令vim /etc/sysconfig/network-scripts/…

Kotlin从0到1,让你一周快速上手!!

声明 大家好&#xff0c;这里是懒羊羊学长&#xff0c;如果需要pdf版以及其他资料&#xff0c;请加入群聊。群里每天更新面经、求职资料&#xff0c;经验分享等&#xff0c;大家感兴趣可以加一下。 Kotlin 声明1.Kotlin基础2. Kotlin函数3.Kotlin进阶4.Kotlin集合5.Kotlin高…

全球顶级的低代码开发平台,你知道几个?

什么是低代码开发平台? 低码开发平台是一个应用程序,提供图形用户界面编程,从而以非常快的速度开发代码,减少了传统的编程工作。 这些工具有助于快速开发代码,最大限度地减少手工编码的努力。这些平台不仅有助于编码,而且还能快速安装和部署。 低码开发工具的好处 低代码平…

【QT教程】QT6数据库操作

QT6数据库操作 使用AI技术辅助生成 QT界面美化视频课程 QT性能优化视频课程 QT原理与源码分析视频课程 QT QML C扩展开发视频课程 免费QT视频课程 您可以看免费1000个QT技术视频 免费QT视频课程 QT统计图和QT数据可视化视频免费看 免费QT视频课程 QT性能优化视频免费看 免费Q…

为什么公共云的弹性能力很难被发挥出来?

作者&#xff5c;王小瑞 AutoMQ 联合创始人 & CEO 云计算通过资源池化实现单位资源成本更优&#xff0c;使企业能够将 IDC 建设、基础软件研发和运维等工作外包给云厂商&#xff0c;从而更专注于业务创新。资源池不仅包括服务器&#xff0c;还包括人才。云厂商集聚了优秀…

ubuntu20.04.3挂载共享文件夹

VMware设置win共享文件夹 在linux执行挂载命令 sudo vmhgfs-fuse /mnt/hgfs/ -o nonempty这样就可以用管理员访问/mnt/hgfs/share

Java全套智慧校园系统源码springboot+elmentui +Quartz可视化校园管理平台系统源码 建设智慧校园的5大关键技术

Java全套智慧校园系统源码springbootelmentui Quartz可视化校园管理平台系统源码 建设智慧校园的5大关键技术 智慧校园指的是以物联网为基础的智慧化的校园工作、学习和生活一体化环境&#xff0c;这个一体化环境以各种应用服务系统为载体&#xff0c;将教学、科研、管理和校园…

Docker仅需3步搭建免费私有化的AI搜索引擎-FreeAskInternet

简介 FreeAskInternet 是一个完全免费、私有且本地运行的搜索引擎&#xff0c;并使用 LLM 生成答案&#xff0c;无需 GPU。用户可以提出问题&#xff0c;系统会进行多引擎搜索&#xff0c;并将搜索结果合并到ChatGPT3.5 LLM中&#xff0c;并根据搜索结果生成答案。 什么是 Fr…