当前位置: 首页 > news >正文

C语言指针之二malloc的用法及详解

一、为什么c语言中要有malloc

malloc就是memory allocate动态分配内存,malloc的出现时为了弥补静态内存分配的缺点,静态分配内存有如下缺点:

1、比如说,传统的一维数组,如int a,使用传统的一维数组需要事先指定数组的长度,而且数组的长度必须是一个常量(宏定义的 常量)

2、传统数组(静态分配),不能手动释放,只能等待系统释放,静态分配的变量在该函数内运行的时候有效,当静态分配的变量所在函数运行完之后,该内存会自动释放。静态分配的内存,是在栈中分配的,其实在C语言中的函数调用也是通过栈来实现的,栈这种数据结构的一个特点就是(先进后出),所以,在调用函数的时候,都是先压入栈中,然后,再从最上面的函数开始执行,最后,执行到main函数结束。动态分配通过malloc分配,是在堆中分配的,堆不是一种数据结构,它是一种排序方式,堆排序。

3、传统数组的长度一旦定义之后,就不能更改,比如说,如果我有一个业务在这之前给分配的大小为100,但是,我现在由于业务数量的增长,原来的大小就无法满足。

4、静态分配不能跨函数调用,就是无法在另一个函数中,来管理一个函数中的内存。静态分配,只在当前函数有效,当,静态分配所在的函数运行完之后,该变量就不能被其他的函数所调用。

二、malloc是什么

malloc其实就是一个可以动态分配内存的函数,从而可以很好的弥补上面静态分配的缺点。

三、malloc怎么使用

1、使用malloc函数的时候,需要包含一个头文件#include

2、malloc函数只接受一个形参如,int *p = (int *)malloc(sizeof(int)).先来解释下这句话的含义,int* p代表一个以int类型地址为内容的指针变量,p这个变量占4个字节(某些计算机),这个p变量是静态分配的一个变量。在某些计算机的前提下,指针变量所占的大小都是一样的,无论是char* 还是long *,因为,这些指针变量里面存放的是一个8位16进制的地址,所以占四个字节,当然这些都是在某些计算机的前提下,并不是所有的都是这样的。说道地址的话,就和计算机的地址总线有关,如果计算机的地址总线是32根,每根地址总线只有两种状态(1或0),32根地址线的话,如果全为1的话,刚好就是一个8位十六进制,一位十六进制等于四个二进制(2^4=16)。32根地址总线可以 表示2^10*2^10*2^10*2^2种状态,可以表示的最大内存为4G,也就是说32根地址总线(也就是四个字节 的指针变量)最大可以表示4G内存。malloc函数会返回开辟空间的首地址,加(int *)的目的是让计算机知道,如何去划分这个开辟的空间,因为char、int 、long这些类型的字节大小是不一样的,我们知道了首地址,还要知道是以几个字节为单元。所以,这句话一共开辟了8个字节(某些计算机上),这也是为什么我写sizeof(int),而不是直接写4的原因。

3、malloc开辟空间所返回的首地址是动态分配的。

四、malloc函数的使用例子

# include # include int main(void) { int i = 5; //分配了4个字节 静态分配 int * p = (int *)malloc(sizeof(4));//指针变量p为静态分配,malloc开辟的空间为动态分配 *p = 5; //*p 代表的就是一个int变量,指针变量p表示是一个以int类型的地址为内容的变量 free(p); //freep(p)表示把p所指向的内存给释放掉,p本身的内存是静态的,不能由程序员手动释放 //p本身的内存只能在p变量所在的函数运行终止时由系统自动释放 return 0; }
# include # include void f(int * q) { *q = 200; //free(q); //把q所指向的内存释放掉,不然后面在使用*p的时候会报错,因为p所指向的内容已经被释放了 } int main(void) { int * p = (int *)malloc(sizeof(int)); //sizeof(int)返回值是int所占的字节数 *p = 10; f(p); //p是int *类型 printf("%d\n", *p); return 0; }
http://www.zskr.cn/news/1483492.html

相关文章:

  • 2026年北京离婚律师实力对比 5位深耕家事各有专长 - 本地品牌推荐
  • MixIO vs Blynk/MQTT:一个更适合Mixly用户的物联网平台选择?
  • 拆解5G基站RRU:FPGA里到底塞了哪些模块?从DUC到DPD,一张图讲清楚
  • 别再死记硬背了!用这5个真实项目案例,帮你彻底搞懂软件工程导论核心概念
  • 变身大冒险:从“半成品代码“到“电脑悄悄话“的神奇变身术
  • 高校外聘教师信息登记与课时工资自动核算桌面工具(C# + SQL Server)
  • JVM 性能调优与线上问题定位方法论
  • 阿贝云服务器挖矿程序攻击预防与处理实用心得
  • 金融行业会议转写防坑指南:夸克、讯飞、随身鹿真实对比
  • TVA为什么是企业智能化升级的战略支点(13)
  • 私有化部署B2B解决方案推荐:2026年最新测评
  • 学了Spring AI Graph再看LangGraph,发现API几乎一模一样
  • 电力工程师必看:手把手教你用Python解析COMTRADE文件(含CFG/DAT文件实战)
  • 2026年AI营销获客工具盘点:4大核心选型维度
  • KMS_VL_ALL_AIO:Windows与Office批量激活的终极技术方案
  • Jsxer:如何快速解码Adobe JSXBIN二进制脚本文件?
  • Android音频策略配置实战:手把手教你读懂audio_policy_configuration.xml(附源码解析)
  • 告别卡顿与依赖错误:保姆级优化你的Unitree Go1 Nano主控开发环境(换源、网关、jtop监控全攻略)
  • ESP32 I2C总线扫盲:如何用Arduino框架和PlatformIO快速扫描并连接你的传感器
  • 用Delphi7和SPComm手撸一个SBUS调试助手:从串口抓包到通道数据可视化
  • 别再死记叉乘公式了!用Python和NumPy玩转向量运算与反对称矩阵
  • F28335 SPI与EEPROM/Flash通信实战:从寄存器配置到数据读写全流程
  • ESP32 I2C驱动OLED屏幕:从硬件连接到显示‘Hello World’的完整流程(附代码)
  • 2026年精选8款文件夹加密软件分享
  • 单人创业,靠 StarLny 搭建数字团队
  • py-spy:不改动代码就能分析 Python 性能
  • F28335 DSP驱动AD7606避坑指南:从原理图焊接到CCS代码调试的完整流程
  • 从‘旋转时钟’到‘整数模n’:手把手用Python代码验证群同构与同态(附完整代码)
  • 告别ifup/ifconfig:Ubuntu 18.04+网络配置,用Netplan这一篇就够了(含YAML避坑指南)
  • 北京GEO优化哪家靠谱?2026主流服务商横向对比与选型指南