函数/代码安全、malloc的低层实现

STM32 malloc函数(堆区)多线程安全问题 我这里只调用一次heap_mutex_init()创建了一个互斥锁,在进入多线程环境前调用即可。当然多个共享资源使用同一个互斥锁会降低资源利用率,也可以改进针对不同的共享资源使用_mutex_initialize(void *sid)创建不同的互斥锁(需要重新实现)。可以通过调试方式确认这些互斥锁有没有生效,观察使用malloc函数时有没有调用_mutex_acquire(osMutexId *sid)和_mutex_release(osMutexId *sid),若调用了说明互斥锁有效。 阅读详情

一般说到代码安全时,一般会涉及这几个方面:
一、函数中的指针操作出现下面几种情况:
1.指针访问无效的内存
2指针所指资源没释放,导致内存空间越占越大。
3.指针已释放资源,又去访问。
二、函数在结束的时候,返回局部变量的地址或引用。
三、代码的线程安全。


  • 如何知道代码或函数是线程安全的?

在函数运行的过程中,可能同一个会导致两个或两个以上的线程来访问变量,那么,如果在时间上出现你先取,我在你还没使用结束的情况下就取值,会导致最终的结果不是我们所要的结果。也就是说“运行程序的结果,随着线程调度的顺序的不同,而出现不同的运行结果。”我们把这种结果称之为程序代码出现了竞态条件,把发生竞态条件的代码段,称为临界区代码段。对于临界区代码段,需要保证它为原子操作,为了保证临界区代码段的原子操作,需要对临界区代码段加互斥锁进行控制。


关键字“volatile”的作用:
在多线程环境中,不允许将其修饰的变量放入到eche缓存中,所有线程读写的都是内存数据段的变量。
这里写图片描述
图中,将a和b取data这句代码翻译成了三句汇编码,对b取data时,是直接从缓存器eax中取得,这样就增加了代码运行效率,但另外也引出了另外一个问题–如果运算器对缓存器中的值发生更改,而系统又没能及时的将更改后的值刷回到内存地址中去,那么,另外的线程访问data时,会访问到旧的数据,导致程序运算结果发生错误。
此时,给data加了“volatile”关键字,编译器会将函数中的两句代码翻译成下图的形式。
这里写图片描述
b的取值也是从地址中进行取值,一旦对data变量发生修改,那么修改结果会直接保存到内存地址中去。


malloc函数的底层实现:

malloc函数的实现是用户通过调用API来访问核函数,核函数为系统自己提供。
malloc在分配内存时,以128k为界限,大于128k,使用do_mmap函数进行内存分配,小于128k,使用do_brk函数进行内存分配,这里通过break指针的移动来分配内存。

堆区的内存结构如下:
这里写图片描述
堆区主要由三部分组成:堆的开始部分(start_brk),堆顶(break),堆的最大限制(rlimit)。从start_brk到break部分,是系统为用户映射好的虚拟地址,可供用户访问,从break往上为未映射的地址空间,用户不可访问,否则会发生段错误“内存非法访问”。

堆的系统调用,主要通过brk,mmap,unmmap这些系统调用完成。
以一个具体例子来说明内存分配原理;
这里写图片描述
情况1.内存分配小于128K时。
1. 图1.当堆区未分配内存时,break和start_brk指向同一个地方,它们都指向数据段的最高地址。
2. 当调用A=malloc(10K)后,系统会自动调用brk()函数,将break指针向下移动10K。
但这里有一个特殊情况:break+10K之后,完成了虚拟内存分配,但并没有物理页与之对应,所以当进程执行到这一块之后,发生缺页中断,这时候,系统才为这块内存分配物理页,如果这块内存分配后却从来不用,那么系统不会为这块区域分配实际内存。
3.调用b=malloc(20k)之后,得到图3操作。
情况2.malloc分配内存大于128K时
这里写图片描述
4.当系统调用e=malloc(200K),malloc分配空间大于128K时,系统调用mmap函数,在堆区和栈区之间为用户分配一块虚拟内存,这样做原因有一下两点:
mmap函数分配的内存可以单独释放,brk函数分配的内存必须要等到break所指向的内存释放之后才可以释放。
5.调用c=malloc(100K)时,如图5.
6.调用free(e),时,e所对应的虚拟地址和物理地址一起释放。如图6
这里写图片描述
7.free(b),图7,此时,只有一个break指针指向堆顶,如果回退,c这块的内存就无法进行管理了, 所以break指针不变。系统上将b视为已经收回的内存,如果再需要分配20K大小的内存时,就有可能将b这块内存分配出去。
8.free(c),此时b和c加起来的内存为120K,还不足128K,所以break不执行收缩这个动作,如果break所指向的最高地址空间的空闲内存大于128K,则执行一个收缩操作,其效果如图9。
这里借鉴了博客malloc的低层实现的过程

手把手教你用aligned_malloc实现内存对齐(附完整代码解析) 本文深入解析了aligned_malloc的原理与实现,手把手教你构建高性能内存对齐分配器。通过剖析经典算法和现代C++解决方案,详细阐述了内存对齐对SIMD指令集、缓存优化及硬件交互的重要性,并提供了完整的代码示例和实战场景分析,帮助开发者彻底掌握动态内存对齐分配技术。 阅读详情

相关推荐

国密(3)- 预主密钥/主密钥计算和Finished消息的加解密

国密的ECC-SM3-SM4-CBC模式下的预主密钥和主密钥的生成过程介绍,以及Finished消息的加解密介绍

weixin_43408952的博客 6509

malloc的底层实现原理

malloc的实现原理

Serven的博客 2万+

NVIDIA DGX Spark实战指南:从开箱到部署200B参数大模型

本文详细介绍了NVIDIA DGX Spark桌面AI超级计算机的开箱体验与实战部署指南。文章深入解析了其Grace Blackwell架构与128GB统一内存的核心优势,并逐步演示了从系统初始化、运行200B参数大模型到进行QLoRA微调的全过程。该设备将高达1 PetaFLOP的AI算力浓缩于桌面,为开发者和研究团队提供了本地化、高性能的AI开发与部署一体化解决方案。

weixin_29274969的博客 2228

malloc底层实现原理

Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全部使用 mmap 来分配,munmap直接释放呢 ? Linux的虚拟内存管理有几个关键概念:1、每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址; 2、虚拟地址可通过每个进程上的页表(在每个进程的内核虚拟地址空间)与物理地址进行映射,获得真正物理地址; 3、如果虚拟地址对应物理...

Allelujah123的博客 7443

告别GIS软件!用R语言ggplot2+ggmapcn绘制出版级世界地图(附5种投影对比图)

本文提供了一份完整的实践指南,教你如何利用R语言及其强大的ggplot2生态系统,结合ggmapcn包,绘制出出版级的世界地图。文章详细对比了五种经典地图投影(如摩尔维德、罗宾森投影)的代码实现与视觉差异,并讲解了如何添加比例尺、指北针等专业元素,最终导出高清PDF,实现从数据分析到专业可视化的全流程代码化操作,彻底告别传统GIS软件。

p5l2m9n4o6q的博客 406

SOPHGO SG2000/SG2002 AI SoC异构架构解析与应用

异构计算架构通过整合不同指令集核心(如RISC-V、Arm和8051)实现性能与功耗的平衡,是现代嵌入式系统和AIoT设备的关键技术。其原理是根据任务特性分配至最适合的计算单元,例如通用计算使用高性能核心,实时任务交由专用核心处理。这种架构在智能视觉、工业检测等场景具有显著优势,能高效处理AI推理、多媒体编解码等任务。SOPHGO SG2000系列SoC采用创新的三核异构设计,集成了0.5-1TOPS的NPU加速器,支持Linux/Android/FreeRTOS多系统并行运行。开发中需注意核心间的IPC通

weixin_30684743的博客 351

malloc的底层实现

malloc是C语言中用于动态分配内存的函数,其底层实现通常是由操作系统提供的。

weixin_48617416的博客 1398

vue3:最新实现腾讯人脸核身+增强版人脸核身使用方法及示例源码,Vue3如何使用腾讯云慧眼人脸核身,提供人脸核身案例、身份信息核验、活体检测与核身比对等示例代码(后端spring与thinkphp)

vue3接入腾讯人脸核身,腾讯云人脸核身Vue3+后端代码,H5人脸核身,vue3 H5如何使用腾讯人脸核身sdk,vue3+thinkphp腾讯人脸核身,Spring Boot接入腾讯云人脸核身教程,hinkphp腾讯人脸核身,vue3人脸核身插件接入流程,vue+spring boot实现腾讯人脸核身,vue3接入腾讯云【增强版人脸核身接入】,vue3 h5微信公众号网页腾讯云慧眼人脸核身,tvue3接入人脸核身SDK,vue3+typescrip+vite接入慧眼实名认证,vue3腾讯云活体人脸核身(

✅ 精选推荐文章 4119

Linux —— 线程安全

一、Linux线程互斥1. 进程线程间的互斥相关背景概念1. 临界资源与临界区的理解2. 互斥与原子性的理解2. 互斥量mutex3. 互斥量的接口1. 互斥量初始化2. 互斥量销毁3. 互斥量加锁4. 互斥量解锁5. 互斥量的使用4. 互斥量实现原理探究1. 加锁是如何保证原子性2. 如何保证锁是原子性的二、可重入vs线程安全1. 概念2. 常见的线程不安全的情况3. 常见的线程安全的情4. 常见的不可重入的情况......

M的博客 1923

8、Windows 部署ollama

一个本地运行大模型的集成框架,目前主要针对主流的LLaMA架构的开源大模型设计,通过将模型权重、配置文件和必要数据封装进由Modelfile定义的包中,从而实现大模型的下载、启动和本地运行的自动化部署及推理流程。此外,Ollama内置了一系列针对大模型运行和推理的优化策略,目前作为一个非常热门的大模型托管平台,已被包括LangChain、Taskweaver等在内的多个热门项目高度集成。

Andy_shenzl的博客 1131

【Mode】微带传输线阻抗

微带线,英文名称为 (Microstrip) 是一种常见的平面传输线,主要用于传输微波频率信号(通常在射频和微波电路重中使用)。

u011699626的博客 243

LSPosed 在 KernelSU 上钩不进去?ZygiskNext 两次重启打通注入

KernelSU 是把 root 权限做到内核层的 Android 方案,但它的模块体系里没有 Zygisk,装好的 LSPosed 常常一条钩子都打不进去。这篇文章讲怎么用 ZygiskNext 补上这块缺失的注入能力:设备状态怎么判断、两个包按什么顺序装、效果怎么验证、开不了机怎么救,照着做完,你就能在 KernelSU 上把 LSPosed 跑起来。 整件事的量不大:两个模块包、两次重启,

gitblog_00369的博客 401

Python爬虫:爬取健身平台运动数据(跑步、骑行轨迹)

通过分析这些运动数据,用户能够了解自己的运动趋势、运动成绩,并作出相应的调整。通过使用Strava的API,我们成功地获取了用户的运动活动信息和运动轨迹数据,并进行了存储与可视化。Strava的API提供了丰富的数据接口,能够通过OAuth2认证获取用户的运动数据,包括历史数据、运动轨迹等信息。Strava的API还提供了获取活动轨迹数据的接口,返回的数据格式通常是GeoJSON格式,适用于地图可视化。随着大数据技术的发展,运动数据的分析和可视化为个人健康管理、运动训练计划的优化等提供了强大的支持。

2201_76125261的博客 1074

UNIX中Malloc和Mfree函数的实现原理

在我们平常的编程过程中,我们的程序经常会涉及到内存的操作,也因此常常调用到内存的分配和释放函数。无论是什么语言工具,都不可避免的会提供给程序员这两个配套的函数,其中C语言中的Malloc函数和Mfree函数是此类型函数的经典代表。那到底在操作系统级的低层,系统是如何实现对内存的合理管理和具体分配,这些都是应用程序员平常在计算机领域都很少去了解的知识。其实这两个函数的实现原理和技巧,可以给程序开发人员在编程技巧上以极大的启发,同时还可以帮助提高程序设计人员在程序设计思维上的技巧。了解这两个函数对我们爱好计算机

LQIUIWSB的专栏 1525

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C和C++内存管理(new、malloc和free、delete)

一图读懂内存分配 总结一下: 栈(堆栈),存放非静态局部变量、函数参数、返回值等 堆,用于程序运行时动态内存分配。 数据段, 存储全局数据和静态数据 代码段,存放可执行的代码,或者只读常量 malloc、calloc和realloc区别? malloc是在堆上动态开辟空间; calloc是堆上开空间+初始化为0; realloc是对已有空间的扩容,扩容有两种方式(原地扩容和异地扩容) 原地扩容和异地扩容的差异就在扩容后地址变了。 下面体验一下calloc的初始化: new & dele

天蓝色,只有一种 756

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

一份每日更新的公共Tracker列表,把BT下载加速做对第一步

BT下载速度慢怎么办?先别急着换线路。多数时候,瓶颈不在网络,而在你的客户端能连上的人太少。Tracker 在 BT 网络里相当于一份共享通讯录:它告诉客户端"还有哪些人正在下载同一个文件",通讯录越厚,可连的对端就越多。开源项目 trackerslist 每天自动检测并更新一份公共Tracker列表,你要做的 Tracker配置 基本就是把这份清单搬进客户端。🔖 ## 先拿到清单:track

gitblog_00138的博客 361

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

c/c++ 动态内存 malloc() free()和 new() delete()

动态内存分配的优势   大家可以移步这个链接查看(为什么需要动态内存分配) c语言的malloc() free()   首先需要包含头文件#include<malloc.h>或者#include<stdlib.h>   函数原型extern void *malloc(unsigned int num_bytes):分配长度为num_bytes字节的内存块,当内存分配成功,返回该内存的地址,分配失败返回NULL #include<stdlib.h> //动态定义

qq_38675397的博客 244

oneTBB 内存分配完整指南:从 Allocator 到内存池与 malloc 替换

oneAPI Threading Building Blocks(oneTBB)不仅提供了并行算法与并发容器,还内置了一整套与处理器数量高度可扩展的内存分配方案。本文基于 [doc/main/reference/source/memory_allocation.rst](https://link.gitcode.com/i/cb3a364b03684d7abfc12ba7d3a0b1aa) 及其全

gitblog_01139的博客 224

APK Installer 使用指南:三步在 Windows 上安装安卓应用

APK Installer 是一款面向 Windows 的开源安卓应用安装工具,解决"装一个 APK 就要先拖出整套模拟器"的问题:它负责解析安装包、展示权限、并把应用装入系统已有的安卓运行环境或通过 ADB 连接的设备,全程不需要虚拟机。 ## 用它能做到什么 - **大屏游戏**:手机游戏装进电脑显示器运行,拖入 APK 完成安装后,游戏以独立窗口呈现,可配合 `Win + Tab` 与其

gitblog_00236的博客 380

C++标准模板(STL)- C 内存管理库 - 分配内存 (std::malloc)

分配 size 字节的未初始化存储。 若分配成功,则返回指向分配的适合对任何标量类型对齐的内存块中,最低(首)字节的指针。 若 size 为零,则行为是实现定义的(可以返回空指针,或某个不可用于访问存储,但必须传递给 std::free 的非空指针)。

qq_40788199的博客 766

预测市场跟单机器人入门:认识 Polymarket Copy Trading Bot 完全指南

Polymarket Copy Trading Bot(预测市场跟单机器人)是一款免费开源的自动跟单交易工具,它能 7×24 小时监控 Polymarket 平台上优秀交易者的最新操作,并根据你的资金规模自动计算仓位、实时下单复制。对于想在预测市场"跟着高手学交易"却没时间盯盘的新手来说,这款跟单机器人可以把人工跟单变成全自动流程。 [![Polymarket预测市场横幅图](https://r

gitblog_00510的博客 197

C/C++内存管理的底层调用逻辑

在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与 free不会。

YISHENG1s的博客 1270

C语言内存安全防线构建(边界检查技术全曝光)

掌握C语言动态内存分配的边界检查,有效防范内存越界与程序崩溃。适用于系统编程、嵌入式开发等场景,详解malloc防护、缓冲区溢出检测与运行时监控技术,提升程序稳定性与安全性,值得收藏。

FastDebug的博客 361

Malloc And Free

http://cache.baidu.com/c?word=malloc%3B%CA%B5%CF%D6%3B%D4%AD%C0%ED&url=http%3A//community%2Ecsdn%2Enet/Expert/TopicView3%2Easp%3Fid%3D5138477&b=19&a=1&user=baidu UNIX中Malloc和Mfree函数的实现原理文展  成都信息工程

liyonghust的专栏 1359

Catime 内嵌 zlib/Deflate 资源解压器:基于 miniz tinfl 的无系统依赖实现解析

这篇技术指南围绕 Catime 仓库中 [libs/miniz/README.md](https://link.gitcode.com/i/0cc24a13b48613b5c417eddfb1a23c44) 的核心内容展开,深入讲解 Catime 如何将 miniz 官方仓库的低层 `tinfl` 解压器进行精简引入,用于解压内嵌的 zlib/Deflate 语言与字体资源,并剖析其背后的 CTA

gitblog_00696的博客 310

malloc realloc kmalloc

malloc是调用VirtualAlloc的。你可以直接调用VirtualAlloc,仅仅保留虚拟地址空间而不提交,这样的话,不会分配物理内存,仅仅保留一段虚拟地址空间不被映射而已。等到需要的时候再提交物理内存。 include/linux/kernel.h里声明了kmalloc()和kfree()。用于在内核模式下申 请和释放内存。 void *kmalloc(unsigned int

aaaaatiger--寻路 1374
上一篇: c语言中i++和++i的区别
下一篇: 数组名和指针的区别
findgeneralgirl
博客等级 码龄9年 62粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值