【一天一个计算机知识】—— 【 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

不止“996”!曝硅谷AI创业圈「极限工作制」:每天16小时、凌晨3点下班、周末也在写代码

不止“996”!曝硅谷AI创业圈「极限工作制」:每天16小时、凌晨3点下班、周末也在写代码

编译 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) “如果你周日去旧金山的咖啡馆,会发现几乎每个人都在工作。” 这是 AI 创业公司 Mythril 联合创始人 Sanju Lokuhitige 最近最直观的感受。去年 11 月,他特地搬到旧金山,只为了更接近 AI 创业浪潮的中心。但很快,他也被卷入了这股浪潮带来的另一面——一种越来越极端的工作文化。 Lokuhitige 坦言,他现在几乎每天工作 12 小时,每周 7 天。除了每周少数几场刻意安排的社交活动(主要是为了和创业者们建立联系),其余时间几乎都在写代码、做产品。 “有时候我整整一天都在编程,”他说,“我基本没有什么工作与生活的平衡。”而这样的生活,在如今的 AI 创业圈里并不算罕见。 旧金山 AI 创业圈的真实日常 一位在旧金山一家 AI

By Ne0inhk
黄仁勋公开发文:传统软件开发模式终结,参与AI不必非得拥有计算机博士学位

黄仁勋公开发文:传统软件开发模式终结,参与AI不必非得拥有计算机博士学位

AI 究竟是什么?在 NVIDIA CEO 黄仁勋看来,它早已不只是聊天机器人或某个大模型,而是一种正在迅速成形的“新型基础设施”。 近日,黄仁勋在英伟达官网发布了一篇长文,提出一个颇具形象的比喻——AI 就像一块“五层蛋糕”。从最底层的能源,到芯片、基础设施、模型,再到最上层的应用,人工智能正在形成一整套完整的产业技术栈,并像电力和互联网一样,逐渐成为现代社会的底层能力。 这也是黄仁勋自 2016 年以来公开发表的第七篇长文。在这篇文章中,他从计算机发展史与第一性原理出发,试图解释 AI 技术栈为何会演化成如今的形态,以及为什么全球正在掀起一场规模空前的 AI 基础设施建设。 在他看来,过去几十年的软件大多是预先编写好的程序:人类设计好算法,计算机按指令执行,数据被结构化存储在数据库中,通过精确查询调用。而 AI 的出现打破了这一模式——计算机开始能够理解图像、文本和声音,并根据上下文实时生成答案、推理结果甚至新的内容。 正因为智能不再是预先写好的代码,而是实时生成的能力,支撑它运行的整个计算体系也必须被重新设计。

By Ne0inhk
猛裁1.6万人后,网站再崩6小时、一周4次重大事故!官方“紧急复盘”:跟裁员无关,也不是AI写代码的锅

猛裁1.6万人后,网站再崩6小时、一周4次重大事故!官方“紧急复盘”:跟裁员无关,也不是AI写代码的锅

整理 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) 过去几年里,科技公司几乎都在同一件事上加速:让 AI 参与写代码。 从自动补全、自动生成函数,到直接修改系统配置,生成式 AI 已经逐渐走进真实生产环境。但最近发生在亚马逊的一连串事故,却给整个行业泼了一盆冷水——当 AI 开始真正参与生产环境开发时,事情可能远比想象复杂。 最近,多家媒体披露,本周二亚马逊内部紧急召开了一场工程“深度复盘(deep dive)”会议,专门讨论最近频繁出现的系统故障——其中,一个被反复提及的关键词是:AI 辅助代码。 一周 4 次严重事故,亚马逊内部紧急复盘 事情的起点,是最近一段时间亚马逊系统稳定性明显下降。 负责亚马逊网站技术架构的高级副总裁 Dave Treadwell 在一封内部邮件中坦言:“各位,正如大家可能已经知道的,最近网站及相关基础设施的可用性确实不太理想。” 为此,公司决定把原本每周例行举行的技术会议

By Ne0inhk
这回真的“装”到了!来OpenClaw全国纵深行,你只需要带一台电脑……

这回真的“装”到了!来OpenClaw全国纵深行,你只需要带一台电脑……

AI Agent 的风,已经从 GitHub 吹到了线下。 过去几个月,越来越多开发者开始讨论一个问题: 当 AI 不再只是聊天,而是可以执行任务,软件会变成什么样? 在这股浪潮中,一个开源项目迅速进入开发者视野——OpenClaw,在 GitHub 上获得大量关注,相关教程、实践案例不断出现。有人用它自动整理资料,有人用它管理开发流程,还有人尝试让它执行复杂的工作流。 很多开发者第一次意识到: AI 不只是工具,它可能成为“执行者”。 不过,在技术社区之外,大多数人对 Agent 的理解仍停留在概念层面。 * AI Agent 到底是什么? * 如何在自己的电脑上运行? * 普通开发者能否真正用起来? 带着这些问题,一场围绕 OpenClaw 的开发者城市行动正在展开。 ZEEKLOG 发起的OpenClaw 全国纵深行将走进 20 个城市,用最直接的方式回答一个问题——如果

By Ne0inhk