C语言编程—内存管理

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

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

注意: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() 函数,但它可以处理重叠的内存区域。它接受三个参数,即目标内存区域的指针、源内存区域的指针和要复制的数据大小(以字节为单位)。

malloc与calloc没有本质区别,malloc之后的未初始化内存可以使用memset进行初始化。

主要的不同是malloc不初始化分配的内存,calloc初始化已分配的内存为0。

次要的不同是calloc返回的是一个数组,而malloc返回的是一个对象。

calloc等于malloc后再memset,所以malloc比calloc更高效。

分配内存空间函数malloc 调用形式: (类型说明符*) malloc (size) 。

分配内存空间函数 calloc calloc 也用于分配内存空间。

为什么多用malloc而很少用calloc?

因为calloc虽然对内存进行了初始化(全部初始化为0),

calloc相当于

p = malloc();

memset(p, 0,size);

相对于malloc多了对内存的写零操作,而写零这个操作我们有时候需要,而大部分时间不需要。

 

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

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

相关文章

【C语言】手把手带你解决青蛙跳台阶问题

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,这里是君兮_&#xff0c;今天更新的是经典递归问题——青蛙跳台阶&#xff0c;在所有有关递归的问题中&#xff0c;青蛙跳台阶是最广为人知的问题之一&#xff0c;可以说&#xff0c;如果你能真正弄懂青蛙跳台阶问…

生产者与消费者问题

本篇文章我们使用C探讨一下生产者与消费者问题. 1. 多线程的引入 我们学习了操作系统, 知道了进程和线程的概念, 但是如果不进行代码实战的话, 会很难理解它们. 特别是编程的初学者(比如我), 在了解了进程和线程后通常会感到疑惑: 多线程怎么用? 为啥我平时写代码没有使用到…

Mybatis源码分析_解析大流程梳理_解析配置文件 (3)

学习mybatis&#xff0c;绕不开一个核心类 Configuration。这个类相当于一个小型数据库&#xff0c;把mybatis里面所有的配置信息基本全部给存储起来了。 package org.apache.ibatis.session;import java.util.Arrays; import java.util.Collection; import java.util.HashMap;…

Vue3+VueCli+TS官方模板简析

使用脚手架安装相关依赖 使用vueCli 安装预设的vuextslessrouter ## 查看vue/cli版本&#xff0c;确保vue/cli版本在4.5.0以上 vue --version## 安装或者升级你的vue/cli npm install -g vue/cli## 创建 vue create vue3_cli_ts_htgl //create vue3_cli_ts_htgl为自…

ELFK日志分析系统并使用Filter对日志数据进行处理

系列文章目录 文章目录 系列文章目录一、FilebeatELK1.FilebeatELK 部署2.Filebeat 节点上操作 二、Filter1.内置正则表达式调用 总结 一、FilebeatELK 1.FilebeatELK 部署 Node1节点&#xff08;2C/4G&#xff09;&#xff1a;node1/192.168.169.10 Elasticsearch Node2节点…

深入浅出之Docker Compose详解

目录 1.Docker Compose概述 1.1 Docker Compose 定义 1.2 Docker Compose产生背景 1.3 Docker Compose 核心概念 1.4 Docker Compose 使用步骤 1.5 Docker Compose 常用命令 2. Docker Compose 实战 2.1 Docker Compose下载和卸载 2.2 Docker Compose 项目概述 2.3 Do…

从0到1搭建spring cloud alibaba +springboot+nacos+dubbo微服务

版本关系&#xff1a; spring cloud alibaba各组件对应关系 创建父工程&#xff0c;pom.xml配置如下&#xff1a; 由以上版本对应关系&#xff1a; springboot版本&#xff1a;2.3.2.RELEASE spring cloud 版本选择&#xff1a;Hoxton.SR9 spring cloud alibaba版本选择&#…

Elasticsearch:增量快照如何工作?

作者&#xff1a;Lutf ur Rehman Elastic 提供许多由讲师指导的面对面和虚拟现场培训以及点播培训。 我们的旗舰课程是 Elasticsearch 工程师、Kibana 数据分析和 Elastic 可观测性工程师。 所有这些课程都会获得认证。如果你想更多了解这些认证方面的知识&#xff0c;请阅读文…

5-NumPy如何创建N维数组?【视频版】

目录 问题视频解答 问题 视频解答 点击观看&#xff1a; 5-如何创建等N维数组&#xff1f;

大佬详细讲解:银行核心项目之测试阶段

最近有小伙伴留言说「想了解核心系统建设中&#xff0c;冒烟、SIT、UAT、回归测试的重点&#xff0c;如何设计测试案例&#xff0c;或相关的资料推荐等」。 这个话题很笼统&#xff0c;测试这一块儿除了业务测试&#xff0c;还有性能测试、安全测试等&#xff1b;以及不同的角…

本地Linux 部署 Dashy 并远程访问

文章目录 简介1. 安装Dashy2. 安装cpolar3.配置公网访问地址4. 固定域名访问 转载自cpolar极点云文章&#xff1a;本地Linux 部署 Dashy 并远程访问 简介 Dashy 是一个开源的自托管的导航页配置服务&#xff0c;具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你…

Sequential用法

目录 1.官方文档解释 1.1原文参照 1.2中文解释 2.参考代码 3.一些参考使用 3.1生成网络 3.2 感知机的实现 3.3组装网络层 1.官方文档解释 1.1原文参照 A sequential container. Modules will be added to it in the order they are passed in the constructor. A…