每个进程会有4G的虚拟地址空间, malloc得到的的地址都是虚拟地址, 并且当malloc的时候, 操作系统并不会将实际的内存分配给进程的, 所以malloc只会占用进程自身的虚拟地址空间。
我以前也做过申请内存的测试,并且写了一个短文:
操作系统: Redhat Linux AS5 32bit
服务器内存: 4G
服务器类型: I32
最近写搜索引擎, 因为创建索引需要大量的内存, 所以对Linux下的大内存申请进行了一些测试.
(1)char * p = (char *)malloc( 2G字节 );
=>申请失败.
(2)char * p = (char *)malloc( 1.9G字节 );
=>申请成功
(3)连续的申请10个300M的内存空间
for ( i=0; i<10; i++ )
p = (char*)malloc(300M字节)
=>前9次成功, 最后1次申请失败
(4)先申请1.9G, 再申请900M
p = (char *)malloc( 1.9G字节 );
p = (char *)malloc( 900M字节 );
=>两次申请都成功.
我的理解如下:
对于在普通默认的2.6.*的linux内核!
32位的机器里, 一个进程的内存地址空间范围是0-3G共4个G, 其中最后一个G是内核态的地址空间, 所以给用户态的内存地址空间只留下了前3个G. 那么这样, malloc能够申请到3G以内的内存才对, 但是结果并非如此.在(1)中我们申请2G的内存都没有申请到, 这是什么原因呢?先让我们看一看实际上进程的4G内存空间都放着或被map着什么:
第0G和第1G:用户态地址空间
第2G:库函数映射等
第3G:内核态内存空间
用户态地址空间中还包含了进程代码本身占用的地址空间, 栈的空间等等.
第2G中, 库函数映射等只占用了很少的一部分空间,还有很多的空闲空间.
现在让我们解释这4个问题:
第(1)个问题, 由上图可以看出, 没有连续的2G的内存, 所以申请2G的连续内存是肯定失败的.
第(2), 申请1.9G的空间是成功的, 这是因为前两个G可能会有1.9G的连续空间.
第(3), 申请了300M*9 = 2.7G是成功的, 是的, 前3G中有可能空间着2.7G的空间, 前两个G中空闲的加上第3个G中空闲的部分. 但是如果一次申请2.7G是不行的, 因为没有连续的2.7G的地址空间. 最后一个300M没有申请成功的原因是, 申请的空间大小不能超过3G的用户态地址空间.
第(4), 比较有意思, 显然那个1.9G是在第1-2G这个地址空间中申请成功的, 后900M是第3个G这片地址空间中申请成功的. 我们一共申请到了2.8G的"内存", 却也不是连续的
相关推荐
引发new/malloc动态申请内存失败的常见原因分析与总结
本文结合以往项目中遇到的多个问题实例,给大家详细总结一下引发动态申请内存失败的常见原因,以供借鉴或参考。
关于malloc报错
报错代码部分示例(C语言)typedef double ElemType; struct BTreeNode { ElemType data; char c; struct BTreeNode* left; struct BTreeNode* right; }; struct BTreeNode* CreateHuffman(ElemType a[]...
【VS开发】malloc申请内存错误分析
每个进程会有4G的虚拟地址空间, malloc得到的的地址都是虚拟地址, 并且当malloc的时候, 操作系统并不会将实际的内存分配给进程的, 所以malloc只会占用进程自身的虚拟地址空间。 我以前也做过申请内存的测试,并且写了一个短文: 操作系统: Redhat Linux AS5 32bit 服务器内存: 4G 服务器类型: I32 最近写搜索引擎, 因为创建索引需要大量的
在使用malloc函数时遇见的常见错误
malloc函数简介 malloc函数在C语言和C++中经常使用,为变量动态分配内存空间。 函数原型 void malloc(int size) 说明:malloc 向系统申请分配指定size个字节的内存空间。如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。 该函数包含在头文件:#include <malloc.h>中 ,使用时需导入头文件*<malloc.h>或者<stdlib.h>** 。注意!当内存不再使用时,应使用free()函数将内存块释放。 常
ARM学习(37)MinGW32 GCC编译申请超过2G内存
笔者来聊一下gcc申请超过2G的内存碰到的问题。
【我的C/C++语言学习进阶之旅】NDK开发运行的时候出现错误signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x940a2e48
信号(signal)机制它其实是进程间通信的一种方式。在处理ndk crash日志的时候可以大概理解为错误码,它描述了错误的大概原因。信号码值描述SIGILL4非法指令,例如损坏的可执行文件或代码区损坏SIGABRT6通过C函数abort()发送;为assert()使用SIGBUS7不存在的物理地址,更多为硬件或系统引起SIGFPE8浮点数运算错误,如除0操作SIGKILL9迅速完全终止进程;不能被捕获SIGSEGV11段地址错误,例如空指针、野指针、数组越界等。
malloc为什么会报错:memory corruption
最近遇到一个问题,很有意思,在此记录下,以备后续参考。 程序运行异常,报错:malloc: memory corruption. 用gdb调试程序,bt如下,程序在申请344 bytes内存时失败。 疑问:344bytes内存并不大,为何会失败呢? 进一步,打开AddressSanitizer,重选编译并运行程序,AddressSanitizer报错如下,报错内容分3部分贴出如下(信息安全,隐藏掉部分堆栈信息): 1.重点:红色字体:heap-buffer-overflow on a...
把“思考”塞进 1 KB:我用纯 C 语言给单片机手搓了一个微型 Transformer 推理引擎
摘要:本文探讨了在64KB SRAM的MCU(如STM32H743)上部署精简Transformer模型的技术方案。通过将6层Transformer压缩至1层(隐藏维度128)、4-bit KV-Cache量化等优化手段,实现了240KB Flash占用和59KB RAM峰值,推理延迟184ms(400MHz Cortex-M7),准确率96.1%。关键创新包括:手工优化矩阵乘(CMSIS-NN)、查表法Softmax/LayerNorm、权重按Tile重排提升Cache命中率(60%→94%)。
PSRAM 报错 malloc fail?内存优化方案
本文深入解析ESP32开发中启用PSRAM后malloc仍失败的问题,揭示多堆架构下内存分配的机制,指出默认malloc不使用PSRAM的根本原因,并提供heap_caps_malloc正确用法、内存碎片处理、初始化检查及最佳实践方案,帮助开发者有效利用外部内存。
【RandLA-Net实战】从零构建隧道点云数据集并训练大场景语义分割模型
本文详细介绍了如何使用RandLA-Net构建隧道点云数据集并进行大场景语义分割模型训练。从数据采集、标注到模型训练与优化,提供了完整的实战指南,特别针对隧道场景的特殊挑战提出了解决方案。通过实际案例展示了RandLA-Net在处理大场景点云数据时的高效性和准确性,为隧道巡检等工程应用提供了可靠的技术支持。
innovus实战攻略 | 用setUsefulSkewMode解锁时序优化的“隐藏技能”!
就像时序优化的“瑞士军刀”,参数虽多,但掌握了分类逻辑后,用起来其实很简单!如果你有更绝的用法,欢迎在评论区分享,大家一起卷起来!简单来说,它就是时序优化的“乾坤大挪移”。通过调整触发器的时钟到达时间,把关键路径的建立时间“借”给非关键路径,从而实现全局时序收敛。别急,这个命令就是你的“时序救星”!(工具最多只能借1.2ns的裕量,防止“借过头”导致新问题!这个参数能帮你兜底!(对关键路径“下死手”,确保优化到位!(设置上限,给工具套上“紧箍咒”!(直接跳过边界,避免优化反噬!(全局管理,防止“借过头”!
申请1G的空间 (是否觉得题目越简单越难做呢)
申请开辟1G的空间,不同的方式便是在不同的地方申请,堆区与栈区的差别很明显的体现出来了,因为栈区大小往往是有限的,需要修改系统的限制。
Unity 第一人称视角控制移动、旋转
第一人称视角操作此功能主要是借鉴YouTube,写的蛮好我就搬运过来让大家也试试。
visual studio 2022 动态分配数组在运行时报错
加上头文件#include <stdlib.h>
GPS从入门到放弃(一) --- GPS基础原理
GPS从入门到放弃(一) — GPS基础原理 GPS,全称Global Positioning System,已经广泛应用于我们的日常生活中了,现在的智能手机 里都会自带GPS定位功能。这是一个美国的全球定位系统,虽然我们现在也有北斗了,但毕竟GPS搞的早,所以先从它开始研究起。 整个GPS系统分三大部分: 地面站 卫星 接收机 地面站负责监控。它们通过接收、测量各个卫星信号,计算卫星的运行轨...
三极管稳压电路仿真分析
Z1的负极连接到三极管的基极,三极管发射极E是输出,形成了一个射极跟随器,也就是说,E极的电压随着B电压变化而变化,但BE之间有一个压降,一般硅管0.7V左右,假设B极是6.7V,那E极就是6.7-0.7=6V,所以就有一个公式VOUT=Vz-Vbe,可以根据VOUT来选择合适的稳压管。从稳压管的SPEC中我们可以看到,Vz@Izt这个参数,指在Izt=20mA时,稳压管的稳压值Vz=5.1V,也就是说流过稳压管的电流在20mA以上,稳压效果最佳。三极管导通之后,E点电压会升高,当升高到Vbe。
HEAP CORRUPTION DETECTED:after Normal block错误的方法解决与分析
先说现象,这个问题的表现现象主要是:在malloc(new(new[]))之后,内存使用正常,但是在free(delete(delete[]))时,就会出错了。 结论:出现这个问题的主要原因是:分配的内存少于实际使用的内测。 比如:char* data = malloc(sizeof(char)*3) data[4]; 最快的检测方法:直接先加大自己分配的内存大小,然后看是否还会报错。如果不会报错了,那说明就是这个问题。 ...
WorkBench3.2 + VxWorks6.8安装教程
按照FTP连接主机和目标机,将整个VxWorks6.8的安装分为两个部分,一是在主机(win10系统,可以使用虚拟机或者实体机,推荐使用虚拟机)上安装workbench3.2,进行bootrom与VxWroks映像文件的生成,二是在虚拟机上安装VxWorks系统 19.10.10 首先很高兴文章能帮到大家,但由于本人已不做该方向良久,私信和评论的很多问题现在已经无法解答,如果大家有什么问题欢迎...
记一次Kylin系统适配老版32位应用的完整踩坑实录:从ldd报错到完美运行
本文详细记录了在Kylin系统上适配32位老版应用的完整过程,从解决ldd报错到构建32位运行环境,再到性能优化与稳定性加固。通过创建安全的32位沙箱环境和精准处理动态库缺失问题,最终实现了老程序在新平台上的完美运行,并分享了可持续维护的兼容环境构建方法。
2026 年 AI 大模型资讯深度研究报告 / 2026 年 3 月 11 日
2026 年已成为 AI 大模型发展的关键拐点年。从 2023 年 ChatGPT 开启的技术奇点,历经多模态突破、推理能力崛起,至 2025 年形成产业爆发态势,AI 大模型正从"技术验证期"迈向"产业落地期"。核心发现技术突破: OpenAI 于 2026 年 3 月 6 日发布 GPT-5.4,首次实现原生计算机操控能力,在 OSWorld 桌面操控测试中以 75% 成功率超越人类 (72.4%),标志着 AI 从"对话工具"向"自主数字员工"的时代跃迁市场格局。
计算机控制技术及应用
《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。
C++内存管理
上一篇文章提到delete可以回收数组内存,这是为什么呢,这就需要理解一下delete底层是调用free,而free是怎么回收数组的呢? 由于free和malloc配对使用,malloc的时候大小已经告诉系统了。 free的时候,系统会比对一下这个地址,是不是malloc申请的,如果不是,不给释放 如果是的话,系统就知道要释放多大内存,因为malloc的时候,系统有记录的。 当然了,申请的地址,也记录了的,否则,就无法比对了。 #include <stdio.h> #include <st
pscad IEEE标准系统搭建说明
pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。
ucosIII+Fatfs MDK编译内存不足
使用正点原子的stm32mini板,按照原子的教程先移植好ucosIII,使用正常,移植好Fatfs,只跑fatfs,也正常,但两者一起使用编译,就出问题了。 MDK编辑器件报错,内存不足。为了查看是什么文件占用了这么大内存,我更换了大内存device,编译成功后查看 .map文件 Total RO Size (Code + RO Data)
WINCC7.3破解文件
WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!
RU DOS版、EFI版32bit/64bit BIOS常用工具
DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。
C++项目:高并发内存池
池化技术(Pooling Technique)是一种以“空间换时间”为核心理念的资源管理策略。它颠覆了传统 “按需申请、用完即毁”的瞬态模式,改为“预申请、缓存、复用”的循环模式。简单来说,就是在系统启动或空闲时,提前向操作系统申请一大块资源保存在“池”中,当业务线程真正需要时,直接从池中“借用”而非“新建”,使用完毕后“归还”给池而非“销毁”。1. 初始化:根据预设容量(如最大连接数、内存池总大小),一次性向操作系统申请足量资源。2. 借用:当外部请求到来时,从池中分配一个空闲资源给请求者。
单链表存储结构与内存对齐整理
==第一次学数据结构,内容有很多不正确之处,还请大家指正。
字符数组动态开辟空间和静态开辟空间
动态分配空间和静态分配空间,最直观的理解是编写代码时分配空间大小还是运行时动态分配空间大小。前者空间分配完成后无法更改,后者是在运行时可以根据自身需要来分配空间大小。例如:char buffer[1000]; //静态分配 /* *动态分配 */ scanf(“%d”,&MAXSIZE); char *buffer=(cha...
1万+



被折叠的 条评论
为什么被折叠?



