C语言中的动态内存管理

在C语言中,动态内存管理是通过一系列的标准库函数来实现的,这些函数包括malloc, free, callocrealloc。它们允许程序在运行时动态地分配和释放内存,这是管理复杂数据结构(如链表、树等)时非常有用的功能。

为什么存在动态内存分配

一些常规的内存开辟方式有:

int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
但是上述的开辟空间的方式有两个特点:
  1. 空间开辟大小是固定的。
  2. 数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道, 那数组的编译时开辟空间的方式就不能满足了。这时候就只能试试动态存开辟了。

malloc

C 语言提供了一个动态内存开辟的函数:
void* malloc (size_t size);

malloc函数用于分配一块指定大小的内存区域。分配的内存是原始的,即未初始化,其中的值是未定义的。

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。如果开辟成功则返回一个指向开辟好空间的指针。如果开辟失败则返回一个NULL指针,因此一定要检查malloc的返回值。

返回值的类型是 void* ,所以 malloc 函数并不知道开辟空间的类型,具体在使用的时候使用者自己
来决定。 如果参数 size 0 malloc 的行为是标准是未定义的,取决于编译器。

free函数可以返回之前通过malloc等函数分配的内存。free(ptr)释放ptr指向的内存块。释放后,ptr不再指向一块有效的内存。

void free (void* ptr);

free函数用来释放动态开辟的内存。

  • 如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
  • 如果参数 ptr NULL指针,则函数什么事都不做。

示例:
 

#include <stdio.h>
#include <stdlib.h>int main() {int *ptr = (int*)malloc(sizeof(int)); // 分配一个整数大小的内存if(ptr == NULL) {printf("Memory allocation failed\n");return 1;}*ptr = 10; // 在分配的内存中存储值printf("Value at ptr: %d\n", *ptr);free(ptr); // 释放内存ptr = NULL; return 0;
}

这段代码使用malloc分配了足够存储一个整数的内存。然后检查malloc返回的指针,确保内存分配成功。接着在分配的内存中存储一个值,最后使用free释放内存,防止内存泄漏。

calloc

C语言还提供了一个函数叫calloccalloc函数与 malloc类似,但有两个不同点:它接受两个参数,用于指定元素的数量和每个元素的大小,并且分配的内存区域会自动初始化为零。
void* calloc (size_t num, size_t size);
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为 0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全 0

#include <stdio.h>
#include <stdlib.h>
int main()
{int *p = (int*)calloc(10, sizeof(int));if(NULL != p){//使用空间}free(p);p = NULL;return 0;
}

所以如果对申请的内存空间要求初始化,则可以很方便的使用calloc函数完成任务。

realloc

realloc函数用于重新调整之前分配的内存块的大小。这可以用于增大或减小内存块。它的出现让动态内存管理更加灵活。比如有时候觉得申请的空间过大或者过小,这时候要对内存的大小做灵活的调整。realloc函数可以做到对动态开辟内存大小的调整。

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

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

realloc 在调整内存空间的是存在两种情况:
  • 情况 1:原有空间之后有足够大的空间。要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
  • 情况2:原有空间之后没有足够大的空间 。原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。

示例:

#include <stdio.h>
#include <stdlib.h>int main() {int *ptr = (int*)malloc(2 * sizeof(int)); // 初始分配2个整数大小的内存if(ptr == NULL) {printf("Memory allocation failed\n");return 1;}ptr[0] = 1;ptr[1] = 2;// 重新调整为4个整数大小的内存int *new_ptr = (int*)realloc(ptr, 4 * sizeof(int));if(new_ptr == NULL) {printf("Re-allocation failed\n");free(ptr);return 1;}new_ptr[2] = 3;new_ptr[3] = 4;for(int i = 0; i < 4; i++) {printf("%d ", new_ptr[i]); // 打印新分配的数组}free(new_ptr); // 释放内存return 0;
}

首先通过malloc分配了一个有2个整数的数组。然后使用realloc增加这个数组的大小至4个整数。在新分配的内存中存储更多的值,然后打印出新的内存块中的所有值。最后使用free释放内存。

需要注意的是每次调用malloc, callocrealloc最终都需要调用free来释放内存,以避免内存泄漏。

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

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

相关文章

硬件基础:运放

理想运算放大器 理想运算放大器放大倍数无穷大&#xff1b;输入端阻抗无穷大&#xff0c;所以输入端电流为0&#xff1b;输出电压和负载无关&#xff0c;不管负载怎么变化&#xff0c;输出电压都是固定的。 还有个就是输出阻抗为0&#xff1b; 输出阻抗越小&#xff0c;输出时就…

Avalonia中如何实现文件拖拽上传

前言 前面我们讲了在Avalonia中如何将View事件映射到ViewModel层感兴趣的读者可以看一下&#xff0c;本章我们将讲一下在Avalonia框架下如何实现文件和文字的拖拽到指定区域进行处理和上传。 先看效果 界面设计比较简单&#xff0c;还是在前一张的基础上加了一个指定区域&…

基于springboot + vue的社区医院信息系统

qq&#xff08;2829419543&#xff09;获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;采用vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xf…

leetcode 622. 设计循环链表

这道题讲了两种方法&#xff0c;第一个代码是用数组实现的&#xff0c;第二个是用链表实现的&#xff0c;希望对你们有帮助 &#xff08;最好在VS自己测试一遍&#xff0c;再放到 leetcode上哦&#xff09; 下面的是主函数&#xff08;作参考&#xff09;&#xff0c;静下心来…

Ubuntu安装向日葵【远程控制】

文章目录 引言下载向日葵安装向日葵运行向日葵卸载向日葵参考资料 引言 向日葵是一款非常好用的远程控制软件。这一篇博文介绍了如何在 Ubuntu Linux系统 中安装贝瑞向日葵。&#x1f3c3;&#x1f4a5;&#x1f4a5;&#x1f4a5;❗️ 下载向日葵 向日葵官网: https://sunl…

动态规划学习——最长回文子序列,让字符串变成回文串的最小插入次数

一&#xff0c;最长回文串 1.题目 给你一个字符串 s &#xff0c;找出其中最长的回文子序列&#xff0c;并返回该序列的长度。 子序列定义为&#xff1a;不改变剩余字符顺序的情况下&#xff0c;删除某些字符或者不删除任何字符形成的一个序列。 示例 1&#xff1a; 输入&…

【我爱C语言】详解字符函数isdigit和字符串转换函数(atoi和snprintf实现互相转换字符串)三种strlen模拟实现

&#x1f308;write in front :&#x1f50d;个人主页 &#xff1a; 啊森要自信的主页 ✏️真正相信奇迹的家伙&#xff0c;本身和奇迹一样了不起啊&#xff01; 欢迎大家关注&#x1f50d;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;>希望看完我的文章对你有小小的帮助&am…

煤矿电力监控系统

煤矿电力监控系统是一种用于煤矿电力系统的监控解决方案。该系统在重点煤矿的矿井变电站、主运输、主通风、主排水、主副提升等重要设备上加装智能用电融合终端&#xff0c;实时监测煤矿重要设备的电流、电压、负载等主要数据变化。为管理人员提供实时监测、报表管理、告警中心…

Centos7中的mysql环境安装以及卸载【Linux】

Linux中的mysql环境安装【Linux】 一. 检测mysql和mariadb是否存在二. 安装mysql2.1查看自身系统版本2.2 查看yum源2.3 选择yum源头2.4 安装yum源2.5 安装mysql2.6 启动mysql服务2.7 首次登录mysql 三. 卸载mysql3.1 关闭mysql服务3.2 查找并删除组件服务3.2.1 查找组件服务3.2…

漏洞复现-速达软件全系产品存在任意文件上传漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

阿里年薪50w和5w都是如何进行需求分析,过来围观!

工作中难免会遇到并不“完美”的需求文档&#xff0c;比如牵一发而动全身却不清晰的交互逻辑、子条目频繁的变更、交流缺失导致的歧义等&#xff0c;都会让测试在项目推进中手足无措。 一份好的需求文档&#xff0c;不止能够加速开发和测试的脚步&#xff0c;还能够提前发现风…

【尘缘送书第五期】Java程序员:学习与使用多线程

目录 1 多线程对于Java的意义2 为什么Java工程师必须掌握多线程3 Java多线程使用方式4 如何学好Java多线程5 参与方式 摘要&#xff1a;互联网的每一个角落&#xff0c;无论是大型电商平台的秒杀活动&#xff0c;社交平台的实时消息推送&#xff0c;还是在线视频平台的流量洪峰…

Unity中Batching优化的GPU实例化(3)

文章目录 前言一、UNITY_SETUP_INSTANCE_ID(v);二、在UnityInstancing.cginc文件中&#xff0c;看一下Unity这句话做了什么1、使用了该 .cginc 后&#xff0c;会自动预定义该函数2、需要满足GPU实例化条件&#xff0c;才会执行对应语句3、满足GPU实例化后&#xff0c;主要执行的…

在UniApp中使用uni.makePhoneCall方法调起电话拨打功能

目录 1.在manifest.json文件中添加权限 2. 组件中如何定义 3.如何授权 4.相关知识点总结 1.在manifest.json文件中添加权限 {"permissions": {"makePhoneCall": {"desc": "用于拨打电话"}} }2. 组件中如何定义 <template>…

创建第一个 Flink 项目

一、运行环境介绍 Flink执行环境主要分为本地环境和集群环境&#xff0c;本地环境主要为了方便用户编写和调试代码使用&#xff0c;而集群环境则被用于正式环境中&#xff0c;可以借助Hadoop Yarn、k8s或Mesos等不同的资源管理器部署自己的应用。 环境依赖&#xff1a; 【1】…

【论文合集】在非欧空间中的图嵌入方法(Graph Embedding in Non-Euclidean Space)

文章目录 1. Hyperbolic Models1.1 Hyperbolic Graph Attention Network1.2 Poincar Embeddings for Learning Hierarchical Representations.1.3 Learning Continuous Hierarchies in the Lorentz Model of Hyperbolic Geometry1.4 Hyperbolic Graph Convolutional Neural Net…

【开源】基于Vue.js的假日旅社管理系统

文末获取源码&#xff0c;项目编号&#xff1a; S 078 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S078。} 文末获取源码&#xff0c;项目编号&#xff1a;S078。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统介绍2.2 QA 问答 三、系统展示四…

【实用经验】如何根据CVE编号找到安全补丁

找到对应补丁页面 例如查找编号为 CVE-2019-0708 的漏洞&#xff0c;访问下面链接即可&#xff0c;替换末尾编号可获取其他漏洞更新补丁。 https://msrc.microsoft.com/update-guide/vulnerability/CVE-2019-0708根据实际情况点击右侧补丁链接即可跳转下载 最后根据实际情况下…

水平自动扩容和缩容HPA;API资源对象NetworkPolicy;Kubernetes用户安全控制;Kubernetes创建普通用户示例

水平自动扩容和缩容HPA&#xff1b;API资源对象NetworkPolicy&#xff1b;Kubernetes用户安全控制&#xff1b;Kubernetes创建普通用户示例 水平自动扩容和缩容HPA&#xff08;本部分操作适合K8s版本>1.23.x) HPA全称是Horizontal Pod Autoscaler&#xff0c;翻译成中文是…

揭秘C语言结构体:通往内存对齐的视觉之旅

揭秘C语言结构体&#xff1a;通往内存对齐的视觉之旅 引言 在C语言的编程旅程中&#xff0c;结构体&#xff08;structs&#xff09;是一个关键而强大的概念。结构体不仅允许我们组织和存储不同类型的数据&#xff0c;而且通过深入了解内存对齐&#xff0c;我们可以更好地优化…