【一天一个计算机知识】—— 【 C/C++ 内存管理与分布】

【一天一个计算机知识】—— 【 C/C++ 内存管理与分布】



⚡ CYBER_PROFILE ⚡
/// SYSTEM READY ///


[WARNING]: DETECTING HIGH ENERGY

🌊 🌉 🌊 心手合一 · 水到渠成

分隔符
>>> ACCESS TERMINAL <<<
[ 🦾 作者主页 ][ 🔥 C语言核心 ]
[ 💾 编程百度 ][ 📡 代码仓库 ]

---------------------------------------
Running Process: 100% | Latency: 0ms


索引与导读

🚩一、C/C++ 内存分布

我们先来看下面的一段代码和相关问题:

#include<stdio.h>#include<stdlib.h>// 【全局/静态区】.data:已初始化的全局变量int globalVar =1;// 【全局/静态区】.data:已初始化的静态全局变量(作用域限制在本文件)staticint staticGlobalVar =1;voidTest(){// 【全局/静态区】.data:已初始化的静态局部变量(生命周期为整个程序)staticint staticVar =1;// 【栈区】:局部变量,函数运行结束自动释放int localVar =1;// 【栈区】:局部数组int num1[10]={1,2,3,4};// 【栈区】:字符数组(注意:"abcd" 会被拷贝到栈上)char char2[]="abcd";// 【指针在栈区】,但指向的 "abcd" 字符串字面量在【常量区/代码段】constchar* pChar3 ="abcd";// 【指针在栈区】,指向【堆区】通过 malloc 分配的内存int* ptr1 =(int*)malloc(sizeof(int)*4);// 【指针在栈区】,指向【堆区】通过 calloc 分配并初始化的内存int* ptr2 =(int*)calloc(4,sizeof(int));// 【指针在栈区】,将 ptr2 原有的【堆区】内存进行扩充/移动int* ptr3 =(int*)realloc(ptr2,sizeof(int)*4);// 手动释放【堆区】内存free(ptr1);free(ptr3);}
在这里插入图片描述

在这里插入图片描述

🚩二、C语言的动态内存管理

🔗Lucy的空间骇客裂缝:C语言动态内存管理

💪C动态内存管理的面试考点

1)realloc的工作机制

voidTest(){int* p2 =(int*)calloc(4,sizeof(int));int* p3 =(int*)realloc(p2,sizeof(int)*10);free(p3 );}
  • 这里需要free(p2)
  • 不需要。 甚至绝对不能这样做
原因在于 realloc 的工作机制:如果 realloc 成功扩容,它会返回一个新的内存地址(可能是原地址,也可能是搬迁后的新地址)。如果返回了新地址,原内存块(p2)会自动被释放。如果你手动执行 free(p2),会导致“重复释放”(Double Free)的错误,这通常会引起程序崩溃

2)malloc/calloc/realloc的区别是什么?

函数功能描述初始化行为参数形式
malloc分配指定字节大小的内存。不初始化。内存里是随机的垃圾值。malloc(size_t size)
calloc分配 n 个元素的内存,并清零。自动初始化为 0calloc(n, size)
realloc调整已分配内存块的大小。不对新增空间进行初始化。realloc(ptr, new_size)

🚩三、C++ 动态内存管理

  • C语言内存管理方式在C++中可以继续使用
  • C++又提出了自己的内存管理方式:通过newdelete操作符进行动态内存管理

1)操作内置类型

C++中,内置类型(如 int, double, char 等)的动态内存分配主要通过 newdelete 运算符来实现

1.1)单个变量的分配和释放

  • 分配:new 类型 或 new 类型(初始值)
  • 释放:delete 指针变量
intmain(){// 1. 分配一个未初始化的 intint* p1 =newint;// 2. 分配并初始化为 100int* p2 =newint(100);// 使用完毕后必须释放内存delete p1;delete p2;// 良好的习惯:将指针置为空,防止野指针 p1 =nullptr; p2 =nullptr;return0;}

1.2)一维数组的分配与释放

处理数组时,需要使用方括号 []

  • 分配:new 类型[元素个数]
  • 释放:delete[] 指针变量 (注意:释放数组必须加 [],否则会导致未定义行为或内存泄漏)
voidmanageArray(){int size =5;// 分配一个长度为 5 的 int 数组int* arr =newint[size];// 初始化数组(C++11 之后也可以使用 new int[5]{1, 2, 3, 4, 5})for(int i =0; i < size;++i){ arr[i]= i *10;}// 释放数组内存delete[] arr;}

2)操作自定义类型

对于自定义类型(如 structclass),C++newdelete 不仅仅是分配内存,它们还负责调用构造函数和析构函数

  • 最核心的差异在于:自定义类型的生命周期管理包含了初始化(调用构造函数)清理(调用析构函数) 的过程
#include<iostream>usingnamespace std;classA{public:A(int a =0):_a(a){ cout <<"A():"<<this<< endl;}~A(){ cout <<"~A():"<<this<< endl;}private:int _a;};intmain(){ A* p1 =(A*)operatornew(sizeof(A)); A* p2 =newA(1);operatordelete(p1);delete p2;int* p3 =(int*)operatornew(sizeof(int));int* p4 =newint;operatordelete(p3);delete p4; A* p5 =(A*)operatornew(sizeof(A)*10); A* p6 =new A[10];operatordelete[](p5);delete[] p6;return0;}

3)operator new与operator delete函数

  • newdelete 是用户进行动态内存申请和释放的操作符,operator newoperator delete 是系统提供的全局函数
  • new 在底层调用 operator new 全局函数来申请空间,delete 在底层通过 operator delete 全局函数来释放空间

  • new 表达式 (new expression): 这是我们在代码中常用的 Type* p = new Type();。它是一个“全自动”过程,做了两件事:
    1. 调用 operator new 分配原始内存。
    2. 调用构造函数初始化对象。
  • operator new (函数): 这是一个类似于 malloc 的函数,它的唯一任务是分配一块指定大小的原始内存,不负责构造对象。

3.1)operator new详解

🔗Lucy的空间骇客裂缝:operator new官方解析
  • 原型:
void*operatornew(size_t size);
  • 工作原理
    • 参数: size 是需要分配的字节数(编译器会自动计算对象大小并传入)。
    • 返回值: 返回指向分配的内存起始地址的 void* 指针。
    • 失败处理: 默认情况下,如果分配失败,它不会返回 nullptr,而是抛出 std::bad_alloc 异常。
    • 自定义行为: 你可以重载全局或类特定的 operator new 来实现自己的内存池或审计逻辑

3.2)operator delete 详解

🔗Lucy的空间骇客裂缝:operator delete官方解析
  • 原型:
voidoperatordelete(void* ptr)noexcept;
  • 工作原理
    • 对应关系delete 表达式会先调用对象的析构函数,然后调用 operator delete 来释放内存。
    • 安全性:根据 C++ 标准,向 operator delete 传递 nullptr 是安全的,函数会直接返回而不执行任何操作。
    • 释放逻辑:在底层,它通常封装了 free() 或者系统底层的内存回收接口。
C++ 中,noexcept 是一个异常说明,它告诉编译器和程序员:这个函数保证不会抛出异常

通过上述两个全局函数的实现知道,operator new 实际也是通过 malloc 来申请空间,如果 malloc 申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过 free 来释放空间的


4)new和delete的实现原理

4.1)内置类型

如果申请的是内置类型的空间,newmallocdeletefree 基本类似,不同的地方是:
new/delete 申请和释放的是单个元素的空间,new[]delete[] 申请的是连续空间,而且 new 在申请空间失败时会抛异常,malloc 会返回 NULL


4.2)自定义类型

  • new 的原理
    1. 调用 operator new 函数申请空间
    2. 在申请的空间上执行构造函数,完成对象的构造
  • delete 的原理
    1. 在空间上执行析构函数,完成对象中资源的清理工作
    2. 调用 operator delete 函数释放对象的空间
  • new T[N] 的原理
    1. 调用 operator new[] 函数,在 operator new[] 中实际调用 operator new 函数完成 N 个对象空间的申请
    2. 在申请的空间上执行 N 次构造函数
  • delete[] 的原理
    1. 在释放的对象空间上执行 N 次析构函数,完成 N 个对象中资源的清理
    2. 调用 operator delete[] 释放空间,实际在 operator delete[] 中调用 operator delete 来释放空间

5)malloc/free和new/delete的区别

malloc/freenew/delete 的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方是:

  1. mallocfree 是函数,newdelete 是操作符
  2. malloc 申请的空间不会初始化,new 可以初始化
  3. malloc 申请空间时,需要手动计算空间大小并传递,new 只需在其后跟上空间的类型即可,如果是多个对象,[] 中指定对象个数即可
  4. malloc 的返回值为 void*,在使用时必须强转,new 不需要,因为 new 后跟的是空间的类型
  5. malloc 申请空间失败时,返回的是 NULL,因此使用时必须判空,new 不需要,但是 new 需要捕获异常
  6. 申请自定义类型对象时,malloc/free 只会开辟空间,不会调用构造函数与析构函数,而 new 在申请空间后会调用构造函数完成对象的初始化,delete 在释放空间前会调用析构函数完成空间中资源的清理释放

💻结尾— 核心连接协议

警告:🌠🌠正在接入底层技术矩阵。如果你已成功破解学习中的逻辑断层,请执行以下指令序列以同步数据:🌠🌠


【📡】 建立深度链接:关注本终端。在赛博丛林中深耕底层架构,从原始代码到进阶协议,同步见证每一次系统升级。

【⚡】 能量过载分发:执行点赞操作。通过高带宽分发,让优质模组在信息流中高亮显示,赋予知识跨维度的传播力。

【💾】 离线缓存核心:将本页加入收藏。把这些高频实战逻辑存入你的离线存储器,在遭遇系统崩溃或需要离线检索时,实现瞬时读取。

【💬】 协议加密解密:评论区留下你的散列码。分享你曾遭遇的代码冲突或系统漏洞(那些年踩过的坑),通过交互式编译共同绕过技术陷阱。

【🛰️】 信号频率投票:通过投票发射你的选择。你的每一次点击都在重新定义矩阵的进化方向,决定下一个被全量拆解的技术节点。


在这里插入图片描述

Read more

OpenClaw六大开源替代方案深度解析,从极简原型到生产级巨兽的全面选型指南

OpenClaw六大开源替代方案深度解析,从极简原型到生产级巨兽的全面选型指南

在AI智能体领域,2025年无疑是属于“Claw”系列的一年。这一年11月,Peter Steinberger上传了一个名为OpenClaw的原型代码,谁也没想到,这个项目会在短短84天内收获20万颗GitHub Star,成为史上增长最快的软件项目。OpenClaw的爆火,就像一颗投入湖面的石子,瞬间激起了整个AI智能体生态的涟漪,一系列轻量级、针对性更强的开源替代方案纷纷涌现,它们各自在代码规模、安全性能、部署难度等维度上做出优化,满足不同开发者的多样化需求。 对于开发者而言,面对市面上五花八门的Claw类项目,如何根据自身的技术背景、部署环境和实际需求,选择最适合自己的方案,成为了一个亟待解决的问题。有的开发者追求极简代码,想快速理解AI智能体的核心逻辑;有的则看重安全性能,需要能直接用于生产环境的可靠方案;还有的专注于边缘计算,希望智能体能在资源受限的硬件上顺畅运行。为了帮大家理清思路,本文将对六大主流开源Claws项目进行深度对比,从项目概述、技术栈、性能指标到适用人群,再到部署要求和核心特性的差异,全方位解析每个项目的优势与不足,最后给出针对性的选型建议,希望能为开发者们

By Ne0inhk

New API 详解:新一代开源大模型统一网关与 AI 资产管理系统(深度 6000 字指南)

New API 详解:新一代开源大模型统一网关与 AI 资产管理系统(深度 6000 字指南) * 开篇:为什么我们需要一个“大模型统一网关”? * 一、项目背景与发展历程 * 二、核心特性详解(为什么 New API 比竞品强) * 1. 统一接口 + 多格式转换(最强兼容性) * 2. 智能路由与高可用 * 3. 精细计费与支付闭环(个人/企业必备) * 4. 现代化管理后台 * 5. 多语言 & 多租户 * 6. 扩展集成 * 7. 安全与可观测性 * 三、支持的模型与渠道(30+ 服务商,100+ 模型) * 四、部署安装完整教程(10 分钟上手)

By Ne0inhk
2025年ChipCamp芯片营地十大开源RISC-V

2025年ChipCamp芯片营地十大开源RISC-V

1、XiangShan ----官方地址:https://github.com/OpenXiangShan/XiangShan ----中科院计算所/中国科学院大学的开源RISC-V项目,面向RISC-V的最前沿技术和场景,使用Chisel语言,打造的高性能超标量乱序RISC-V处理器,经过雁栖湖,南湖,昆明湖多代版本的演进,代码和文档全部开源。 ----作为专业的超大规模RISC-V开源项目,在github上获得6.8K个star。 ----被ChipCamp收录在:https://gitcode.com/ChipCamp/XiangShan。 2、RISCV-BOOM ----官方地址:https://github.com/riscv-boom/riscv-boom ----在Github上有2K个星,其BOOM-v1.0代码在ChipCamp芯片营地行了通读。 ----被ChipCamp收录在:https://gitcode.com/ChipCamp/BOOM-v1.0。 3、e203_hbirdv2 ----官方地址(国际):https:

By Ne0inhk
git bash|下载、安装与配置(Windows11)

git bash|下载、安装与配置(Windows11)

序言 Git 是一个 分布式版本控制系统(DVCS),用于高效、可靠地跟踪文件(尤其是代码)的变更历史。它由 Linus Torvalds 于 2005 年创建,最初是为了管理 Linux 内核开发而设计。 🌟 核心特点 1. 分布式 每个开发者本地都拥有完整的代码仓库(包括全部历史记录),不依赖中央服务器也能提交、分支、合并等操作。 2. 高性能 Git 在处理大型项目时依然快速,无论是提交、切换分支还是合并,都经过高度优化。 3. 数据完整性 Git 使用 SHA-1 哈希值标识每次提交和文件内容,确保历史记录不可篡改(“内容寻址”存储)。 4. 强大的分支与合并 创建、切换、合并分支非常轻量快捷,鼓励基于分支的开发流程(如 Git

By Ne0inhk