【C语言】malloc()函数详解(动态内存开辟函数)

news2024/12/22 13:09:46

 一.malloc()函数简介

我们先来看一下cplusplus.com - The C++ Resources Network网站上malloc()函数的基本信息:

1.函数功能

可以看到,malloc()函数的功能是:向内存申请一块连续可用的空间,并返回指向块开头的指针.

2.函数参数

该函数有1个参数,是:

void* malloc (size_t size);

1>.size_t size

参数的类型size_t(无符号整型),它表示要开辟的内存块的大小(以字节为单位),它的作用是告诉函数需要动态开辟多少个字节的空间.

在使用malloc时,一般参数传递的形式为(sizeof(要开辟的变量名)*要开辟的个数).

当然也可以直接给malloc传一个具体的数字作为参数,比如:malloc(40);这样malloc()函数就会开辟一个大小为40字节的空间给你使用.

3.函数返回值

函数的返回值类型void*(无类型指针),它的作用是在函数运行结束后返回给主函数动态开辟好的空间块的首地址,以便后续进行对这块内存空间的使用.

但要注意:如果在malloc()函数在开辟的过程中遇到了无法分配请求的内存块(即遇到了开辟失败的情况),那么就会返回一个NULL指针,因此malloc的返回值一定要进行检查!

4.函数头文件

该函数包含在头文件<stdlib.h>中.

5.函数生成空间(与calloc区别)

malloc()函数生成的空间内容是不会初始化的!

我们可以调试一下,打开监视窗口查看malloc()函数开辟的内存空间存放的内容:

不会调试使用监控查看程序运行状况的可以移步:

【实用调试技巧】总是找不到Bug?手把手教你在vs2022中调试程序icon-default.png?t=N7T8https://blog.csdn.net/weixin_72357342/article/details/133823086?spm=1001.2014.3001.5502

可以看到,malloc()函数开辟的内存空间中存放的值是随机值,我们后续需要初始化后再进行使用.

而与之相对的另一个动态开辟函数calloc则会开辟一段已经全部初始化为0的空间:

想要了解更多关于calloc()函数的内容可以移步:

【C语言】calloc()函数详解(动态内存开辟函数)icon-default.png?t=N7T8https://blog.csdn.net/weixin_72357342/article/details/133975677我们在这篇就不多赘述了,只简述他们俩在开辟空间方面的区别.


二.malloc()函数的具体使用

malloc()函数的使用场景是:当我们想要使用一块连续的可以按需求调节大小的空间时,我们可以使用malloc()函数来实现这一诉求.

需要特别注意的是!使用malloc()函数动态开辟的内存空间是必须使用free()函数释放还给操作系统的,如果不释放的话就会造成内存泄漏!

内存泄漏:如果动态开辟的内存没有被释放,那么这些内存就会一直占用系统资源,从而导致内存泄漏。内存泄漏会导致程序运行速度变慢,甚至崩溃。

对free()函数还不太了解的可以移步这里:

【C语言】free()函数详解(动态内存释放函数)icon-default.png?t=N7T8https://blog.csdn.net/weixin_72357342/article/details/133975657

1.使用malloc()函数完成动态整型数组空间的开辟

如下,我们使用malloc()函数开辟一个整型数组:

我们给malloc()函数传入:sizeof(int)*10(即10个整型大小的字节数,即40byte).

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>

int main()
{
	int* p = (int*)malloc(sizeof(int) * 10);   //动态开辟内存空间

	if (p != NULL)                          //检验动态开辟空间是否成功
	{
		int i = 0;
		for (i = 0; i < 10; i++)            //如果成功,则给这10个整型赋值
		{
			*(p + i) = i;
			printf("%d\n", *(p + i));
		}
	}
	else
	{
		printf("%s\n", strerror(errno));   //如果失败,则打印失败错误信息
        return 0;                          //失败则不需要进行下面的释放和置空操作了,可以直接退出
	}

	free(p);         //使用完后向系统归还动态开辟的内存空间
	p = NULL;              //将p指针置为空,避免p成为野指针

	return 0;
}

在vs编译器中运行查看结果:

可见malloc()函数成功的开辟出了40个字节的空间来存放这10个整型数据元素.

而如果我们将动态内存开辟的空间大小改为INT_MAX(即2147483647),动态内存开辟就会失败,并告诉我们原因:

这里还有需要注意的点是,用malloc()函数申请0个空间是一种未定义的行为,不同的编译器会有不同的解决方法,但这样的操作的没有实际意义的.


2.使用malloc()函数完成动态结构体空间的开辟

创建好结构体变量后,我们给malloc()函数传入:sizeof(PeoInfo)*3(即3个PeoInfo类型大小的字节数).

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>

//人的信息-结构体
typedef struct PeoInfo
{
	char name[20];
	int age;
	char sex[5];
	char addr[20];
	char tele[11];//电话11位,留一位给'\0';
}PeoInfo;

typedef struct Contact
{
	PeoInfo* data;  //存放人的信息
	int sz;         //用来记录当前已经存放的信息的个数
	int capacity;   //记录当前通讯录的最大容量
}Contact;

int main()
{
	Contact con;
	PeoInfo* ptr = (PeoInfo*)malloc(sizeof(PeoInfo)*3);   //动态开辟空间

	if (ptr == NULL)            //如果开辟失败,则打印错误原因
	{
		perror("InitContact::calloc");
		return;
	}

	free(ptr);         //使用完后向系统归还动态开辟的内存空间
	ptr = NULL;              //将p指针置为空,避免p成为野指针

	return 0;
}

在vs编译器中查看结果:

可见malloc()函数成功的开辟出了3个PeoInfo类型的空间来存放这3个元素.


结语

以上就是malloc()函数的详解,希望能对大家有所帮助!

学海漫浩浩,我亦苦作舟!一起学习!一起进步!

相关文章推荐

【C语言】free()函数详解(动态内存释放函数)

【C语言】realloc()函数详解(动态内存开辟函数)

【C语言】calloc()函数详解(动态内存开辟函数)

【C语言实战项目】通讯录(动态增容版)

...


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

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

相关文章

关于iterm2的美化

iterm2 美化 笔者公司最近给发了一个新 M1 mac pro&#xff0c;所以一些软件需要重新安装。其中比较麻烦就是iterm2的一个美化工程 &#xff0c; 由于每次安装的效果都不尽相同所以这次写一个博客来记录一下 安装的过程 。 全程高能开始&#xff1a; 使用brew 来安装 iterm2 …

26. 通过 cilium pwru了解网络包的来龙去脉

pwru是一种基于eBPF的工具,可跟踪Linux内核中的网络数据包,并具有先进的过滤功能。它允许对内核状态进行细粒度检查,以便通过调试网络连接问题来解决传统工具(如iptables TRACE或tcpdump)难以解决甚至无法解决的问题。在本文中,我将介绍pwru如何在不必事先了解所有内容的…

C++ 模板类编译前需要实例化

在复习list容器的模拟实现&#xff0c;遇到了模板未实例化导致代码报错的问题&#xff0c;list的模拟实现可以看下面这篇文章&#xff0c;这里就不多赘述了&#xff0c;直接切入正题。Clist模拟http://t.csdnimg.cn/N6BGh现在的情况是我们已经模拟实现了list类&#xff0c;想在…

1024 漏洞综合项目演示(第十七课)

1024 漏洞综合项目演示(第十七课) 一 渗透流程 前期交互&#xff08;Reconnaissance&#xff09;&#xff1a;这是一个信息收集的阶段&#xff0c;黑客或攻击者会收集目标系统或网络的信息&#xff0c;例如域名、IP地址、子网结构、网络拓扑等。 信息收集&#xff08;Informa…

开源博客项目Blog .NET Core源码学习(4:生成验证码)

开源博客项目Blog中的后台管理登录界面中支持输入验证码&#xff08;如下图所示&#xff09;&#xff0c;本文学习并记录项目中验证码的生成及调用方式。   博客项目中调用VerifyCode类生成验证码&#xff0c;该类位于App.Framwork项目中&#xff0c;命名空间为App.Framwork…

[Docker]一.Docker 简介与安装

一、Docker简介与为什么要用 Docker 1.1、Docker 介绍 Docker 是一个跨平台的开源的 应用容器引擎 &#xff0c;诞生于 2013 年初&#xff0c;基于 Go语言 并遵从 Apache2.0 协议开源, Docker 可以把它理解成虚拟机&#xff0c;但是 Docker 和传统虚拟化方式 有所不同 …

玩转视频剪辑全攻略:批量添加上自定义封面的技巧

在进行视频编辑的过程中&#xff0c;我们经常需要为视频添加引人入胜的封面&#xff0c;以吸引观众的注意力。以下是一份详细的全攻略&#xff0c;指导你如何批量添加自定义的视频封面。 首先&#xff0c;你需要在浏览器中搜索并下载“固乔智剪软件”&#xff0c;这是一款功能强…

精通Linux系列第三章:文件系统管理与权限设置(含目录结构思维导图)

文章目录 一、前言二、文件系统概述2.1 文件系统的定义2.2 常见的Linux文件系统2.3 查看当前Linux系统所使用的文件系统2.4 怎么使用特定的文件系统2.5 文件系统的层次结构 三、文件和目录管理3.1 文件和目录的基本概念3.2 创建文件和目录3.3 查看文件和目录信息3.4 复制、移动…

codeforces (C++ Simple Design)

题目&#xff1a; 翻译&#xff1a; 思路&#xff1a; 1、难点在于读题&#xff0c;输入两个数x&#xff0c;k&#xff0c;从x开始递增寻找最小可整除k的数。 代码&#xff1a; #include<iostream> using namespace std; int main() {int x, k;int n;cin >> n;…

使用 OpenGL 渲染会旋转 会变色的三角形(LearnOpenGL P3)

文章目录 前言代码 前言 本文参考文献&#xff0c;侵删&#xff01;LearnOpenGL - 你好&#xff0c;三角形 本文将假设您完成了 OpenGL 的配置&#xff0c;并且使用 VAO、VBO 渲染图形 由于时间问题&#xff0c;代码的详细讲解将在几日内给出~ 代码 #include <glad/glad…

UML类图中各箭头表示总结

UML类图中各箭头表示总结 1、泛化2、实现3、依赖4、关联5、聚合6、组合 在UML类图中&#xff0c;箭头关系是用来表示类之间的关系的。箭头关系的种类有以下几种&#xff1a; 1、泛化 泛化&#xff1a;表示类之间的继承关系。箭头从子类指向父类。箭头&#xff1a;实线空心三角…

【计算机网络】UDP/TCP协议

文章目录 :peach:1 UDP协议:peach:1.1 :apple:UDP协议端格式:apple:1.2 :apple:UDP的特点:apple:1.3 :apple:UDP的缓冲区:apple:1.4 :apple:UDP使用注意事项:apple:1.5 :apple:基于UDP的应用层协议:apple: 2 :peach:TCP协议:peach:2.1 :apple:TCP协议端格式:apple:2.2 :apple:确…

《windows核心编程》第3章 内核对象

一、内核对象简介 1.1 内核对象有哪些 令牌对象 token、事件对象 Event、文件对象 File、文件映射对象 Mapping_File、线程对象 Thread、时钟对象 Timer、线程池对象 ThreadPool、I/O完成端口对象 Completion port、工作对象 job、邮槽对象 mailslot、互斥对象 Mutex、管道对…

Hook原理--逆向开发

今天我们将继续讲解逆向开发工程另一个重要内容--Hook原理讲解。Hook&#xff0c;可以中文译为“挂钩”或者“钩子”&#xff0c;逆向开发中改变程序运行的一种技术。按照如下过程进行讲解 Hook概述Hook技术方式fishhook原理及实例符号表查看函数名称总结 一、Hook概述 在逆…

LeetCode刷题---有效的括号

这里用到了栈的思想 栈(stack)是限定仅在表尾进行插入或者删除的线性表。对于栈来说&#xff0c;表尾端称为栈顶&#xff08;top&#xff09;&#xff0c;表头端称为栈低&#xff08;bottom&#xff09;。不含元素的空表称为空栈。因为栈限定在表尾进行插入或者删除&#xff0c…

生成包含10个随机字母或数字的字符串,然后统计每个字符的出现次数

from random import choices from string import ascii_letters, digitsx .join(choices(ascii_lettersdigits, k10)) d dict() # 创建空字典 for ch in x:d[ch] d.get(ch, 0) 1 # x中有ch字符,个数1,并作为字典的值 print(x) print(d)也可以使用collections模块的defaul…

从车窗升降一探 Android 车机的重要 API:车辆属性 CarProperty

前言 前面我们介绍过 Android 车机 Automotive OS 的几块重要内容&#xff1a; 一文了解 Android 车机如何处理中控的旋钮输入从实体按键看 Android 车机的自定义事件机制深度入门 Android 车机核心 CarService 的构成和链路 本篇文章我们聚焦 Android 车机上最重要、最常用…

LeetCode--180 连续出现的数字

文章目录 1 题目描述2 结果示例3 解题思路3.1 MySQL 代码 4 知识拓展 1 题目描述 Logs表: ---------------------- | Column Name | Type | ---------------------- | id | int | | num | varchar | ----------------------在 SQL 中&#xff0c;id …

Mybatis的SqlRunner执行流程

Mybatis的SqlRunner执行流程 SqlRunner exec new SqlRunner(connection); Map<String, Object> row exec.selectOne("SELECT * FROM PRODUCT WHERE PRODUCTID ?", "FI-SW-01");connection.close();assertEquals("FI-SW-01", row.ge…

YOLOv5算法改进(19)— 手把手教你去更换NMS(DIoU-NMS/CIoU-NMS/EIoU-NMS/GIoU-NMS/SIoU-NMS)

前言:Hello大家好,我是小哥谈。YOLOv5中的NMS指非极大值抑制(Non-Maximum Suppression),它是一种用于目标检测算法中的后处理技术。在检测到多个重叠的边界框时,NMS可以帮助选择最佳的边界框。NMS的工作原理是首先根据预测边界框的置信度对它们进行排序,然后从置信度最高…