C语言基础入门48篇_46_malloc与free(malloc申请堆返回void要指针强转、free释放堆,只需堆内存首地址、malloc配合sizeof增加可读性、注意出{}作用域导致无法释放)

2023-11-16

从上篇C语言基础入门48篇_45_内存的分区:全局区、栈区、堆(全局区main执行前分配好,存储程序代码及全局变量、栈区M级别随着函数调用返回自动分配回收,存储局部变量、堆大量内存动态分配、回收的内存区域)知道,不管是全局区还是栈区的内存,他们通常都只占可以使用的内存的一小部分,大量的内存被操作系统控制,按需动态分配内存一直都存在,但是我们程序是否能够使用,使用哪块地址的内存,取决于操作系统如何分配给我们,被操作系统控制管理的动态分配、回收的内存区域,就称为堆
本篇介绍c语言中进行申请堆和释放堆中内存的函数

int长度表示:
int 变量依赖于编译器字长。编译器字长有16位,32位,64位三种。

  • 对于16位编译器,int的长度为2字节,即2进制的16位。
    写作16进制时,4位二进制用一位16进制数表示,所以表示int需要用4位16进制数。如0xABCD。

  • 对于32位和64位编译器,int长度为4字节,即2进制32位。
    写作16进制时,需要用8位16进制数表示,如0x12345678。

1. malloc的基本使用


malloc的函数原型是: void *malloc( size_t size );

  • size:表示要申请的堆空间的大小,单位字节
  • 返回值是一个void*类型的指针,malloc会将分配得到的空间的内存首地址返回

之所以采用void*类型指针,是因为任何指针类型都可以转为void,void转其他类型是需要强转的,malloc无法提前知道我们申请的空间用于怎样的类型,先返回一个void*类型,自行根据需求进行强转。因此,通常我们需要将返回值进行指针强转。

#include <stdlib.h>
#include<stdio.h>
int main(int argc, char* argv[])
{
	//申请4字节的空间,作为存储int变量使用
	//申请得到的空间首地址,赋值给pValue指针
	//malloc返回的是void*,需要进行强转
	int* pValue = (int*)malloc(4);

	//每次返回的指针是不同的,可以通过修改指针值
	*pValue = 0x11111111;
	printf("%0x\r\n",*pValue);
	return 0;
}

运行结果:
在这里插入图片描述

根据指针操作可知,我们也可以同时申请大于一个元素的空间地址,在不同的地址上内存存储数据:

#include <stdlib.h>
#include<stdio.h>
int main(int argc, char* argv[])
{
	//申请12字节的空间,作为存储3个int变量使用
	//申请得到的空间首地址,赋值给pValue指针
	int* pValue = (int*)malloc(12);

	//修改值
	*pValue = 0x11111111;
	printf("%0x\r\n", *pValue);
	*(pValue + 1) = 0x22222222;
	printf("%0x\r\n", *(pValue + 1));
	*(pValue + 2) = 0x33333333;
	printf("%0x\r\n", *(pValue + 2));
	return 0;
}

运行结果:
在这里插入图片描述

2. free的基本使用


分房间会需要各种信息,但是退房是比较简单的,无需各种信息。

free的函数原型为:void free( void *memblock );
可以看到,free没有返回值,只有一个参数,我们将之前申请的堆内存首地址传递给free即可

#include <stdlib.h>

int main(int argc, char* argv[])
{
    //申请12字节的空间,作为存储3个int变量使用
    //申请得到的空间首地址,赋值给pValue指针
    int* pValue = (int*)malloc(12);

    //修改值
    *pValue = 0x11111111;
    *(pValue+1) = 0x22222222;
    *(pValue+2) = 0x33333333;

    free(pValue);
    return 0;
}

程序执行时如果一直不释放内存,就会一直在做积累,造成内存泄漏。
但是要注意,若传递给free的地址,并不是之前申请过的堆内存地址,则会出现错误。

3. malloc配合sizeof使用


在实践中,malloc一般配合sizeof使用,无需了解数据所占内存,增加代码的可读性。

#include <stdlib.h>

int main(int argc, char* argv[])
{
    //申请12字节的空间,作为存储3个int变量使用
    //申请得到的空间首地址,赋值给pValue指针
    int* pValue = (int*)malloc(sizeof(int)*3);

    //修改值
    *pValue = 0x11111111;
    *(pValue+1) = 0x22222222;
    *(pValue+2) = 0x33333333;
    return 0;
}

4. 内存泄漏问题


如果对于堆内存,只申请不释放,就会造成资源的泄漏。
某些情况,因为代码的不规范,会导致无法释放资源:

void MyFun()
{
    int* pValue = (int*)malloc(12);

    //修改值
    *pValue = 0x11111111;
    *(pValue + 1) = 0x22222222;
    *(pValue + 2) = 0x33333333;
}

int main(int argc, char* argv[])
{
    MyFun();
    return 0;
}

上述代码:在MyFun()运行结束之后,pValue作为MyFun()中的局部变量,出了{}作用域就会被释放,main函数运行完是无法对堆中的内存进行释放的,这就造成了不可挽救的内存资源泄漏的问题,一定不要忘记了使用malloc()与free成对使用

5. 学习视频地址: malloc与free

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言基础入门48篇_46_malloc与free(malloc申请堆返回void要指针强转、free释放堆,只需堆内存首地址、malloc配合sizeof增加可读性、注意出{}作用域导致无法释放) 的相关文章

随机推荐

  • 前端react框架的部分总结

    前端react框架的部分总结 react的优势 react相对其他框架优势 高性能高效率 实现了前端界面的高性能高效率开发 所以说react很擅长处理组件化的页面 和vue的区别 在React中 一切都是JavaScript 所有的组件的渲
  • Android APP应用启动页白屏(StartingWindow)优化

    转自 https www cnblogs com whycxb p 9312914 html 本人采用这种方法没有效果 启动图片出来第一帧 我应用的第一帧也出来了 启动背景颜色没有调试出来 Theme AppCompat Light Dar
  • Java基础-一些容易被人忽视却重要的Java基础知识(二)

    文章目录 一 重载和重写 1 重载 2 重写 一 重载和重写 1 重载 被重载的方法必须改变参数列表 参数个数或者类型 顺序不一样 被重载的方法可以改变返回类型 被重载的方法可以改变访问修饰符 可以使用新的或更广的检查异常 方法能够在同一类
  • java动态生成pdf文件的方法

    java动态生成pdf文件 文章目录 java动态生成pdf文件 前言 一 生成pdf模板 二 使用步骤 1 使用jar包 2 pdf实现方法 总结 前言 java开发过程中难免会遇到生成文件的需求 这里简单介绍一下关于pdf格式的文件的动
  • python常见的面试题,看你都掌握了吗

    前言 Python是目前编程领域最受欢迎的语言 在本文中 我将总结Python面试中最常见的50个问题 每道题都提供参考答案 希望能够帮助你在2019年求职面试中脱颖而出 找到一份高薪工作 这些面试题涉及Python基础知识 Python编
  • usb转网口转换器经常自动断网

    问题 最近使用一个usb转网口的扩展坞 发现和其它机器通信时 经常会自动断网 原因 和设备的电源管理策略有关 USB设备的 允许计算机自动关闭此设备以节约电源 选项默认是选中的 而网络设备的此选项默认值是未选中 解决办法 打开设备管理器 找
  • MATLAB基本语法详解

    MATLAB基本语法详解 下面内容 变量 M Files 决策 循环容易掌握 命令 数据类型 运算符不需要记住 用了再查 变量 每个MatLab变量可以是数组或者矩阵 最简单的方法指定变量 x 3 定义并初始化 赋值 变量x MATLAB上
  • 搭建redis主从服务 :master_link_status:down 主从无法连接问题汇总

    1 问题描述 主从无法连接问题 2 搭建 https blog csdn net ling811 article details 53637257 https blog csdn net qq 24113267 article detail
  • 双机热备 ip地址_SBC双机热备方案

    概述 随着通信全IP化的进程 现代企业中基于IP的语音 视频 会议 融合通信已广泛应用 同时企业通信也面临着新挑战 包括安全攻击 跨网NAT穿越以及业务稳定运行 高可靠方案尤为重要 因此在组网中部署SBC Session Border Co
  • NPN和PNP三极管原理以及应用电路设计

    一 基本概念与原理 三极管最主要的功能是电流放大 模拟电路 和开关作用 数字电路 常用的三极管有 S9014 S8550等型号 三极管由两个PN结构成 共用的一个电极成为三极管的基极 用字母b表示 其他的两个电极成为集电极 用字母c表示 和
  • 安卓加固基础(二)

    4 反调试 4 1 思路一 一个进程最多只能被一个进程ptrace 本文章主要针对安卓so反调试和最初的加壳方法进行了一下总结 在处于调试状态时 Linux会向 proc pid status写入一些进程状态信息 比如TracerPid字段
  • 【leetcode 力扣刷题】删除字符串中的子串or字符以满足要求

    删除字符串中的子串或者字符以满足题意要求 1234 替换子串得到平衡字符串 680 验证回文串 917 仅仅反转字母 1234 替换子串得到平衡字符串 题目链接 1234 替换子串得到平衡字符串 题目内容 题目中给出了平衡字符串的定义 只有
  • TypeScript 初识笔记

    目录 一 基础静态类型和对象类型 二 类型注解和类型推断 三 元组的使用和类型约束 四 接口 五 类 六 联合类型和类型保护 七 枚举 八 泛型 九 tsconfig json文件 TypeScript 其实就是 JavaScript 的超
  • 教程:在Vivado中指定VSCode作为文本编辑器

    教程 在Vivado中指定VSCode作为文本编辑器 更新历史 20190325 首次发布 20201027 对本文第三步中需要填写的内容做了修改 使得VSCode能够实现光标的自动定位 该修改的做法是 HK Journalist 在评论中
  • Vue组件间通信方式都有哪些?

    一 组件间通信的概念 组件间通信这个词进行拆分 组件 通信 都知道组件是vue最强大的功能之一 vue中每一个 vue可以视之为一个组件通信指的是发送者通过某种媒体以某种格式来传递信息到收信者以达到某个目的 广义上 任何信息的交通都是通信组
  • 一个方案提升Flutter内存利用率(干货)

    背景 我们闲鱼使用的图片方案是自研的外接纹理方案 Android侧创建SurfaceTexture 通过FlutterJNI注册到Flutter engine里 最后返回texture id给Flutter应用层 应用层使用Texture
  • 前端系列之CSS(布局)

    1 行布局 2 多列布局 3 混合布局 4 圣杯布局 5 双飞翼布局
  • 大数据项目实战——基于某招聘网站进行数据采集及数据分析(六)

    大数据项目实战 第六章 数据可视化 学习目标 掌握 Sqoop 数据迁移工具的迁移工具的使用 熟悉关系型数据库 MySQL 掌握 SSM JavaEE 开发框架的整合及应用 掌握 ECharts 前端框架的使用 本篇将应用 Sqoop 将
  • TCGA各种肿瘤数据的20多种不同玩法/挖掘方法

    肿瘤基因组图谱 The Cancer Genome Atlas TCGA 计划是由美国国家癌症研究院 National Cancer Institute NCI 和美国国家人类基因组研究所 National Human Genome Res
  • C语言基础入门48篇_46_malloc与free(malloc申请堆返回void要指针强转、free释放堆,只需堆内存首地址、malloc配合sizeof增加可读性、注意出{}作用域导致无法释放)

    从上篇C语言基础入门48篇 45 内存的分区 全局区 栈区 堆 全局区main执行前分配好 存储程序代码及全局变量 栈区M级别随着函数调用返回自动分配回收 存储局部变量 堆大量内存动态分配 回收的内存区域 知道 不管是全局区还是栈区的内存