10x程序内存模型

admin 2025年2月11日08:35:06评论13 views字数 2810阅读9分22秒阅读模式

关注公众号,后台回复 找书+ C++Primer 获取C++相关电子书。

面向对象编程技术的核心和精髓。

内存分区模型

C++程序在执行时,将内存大方向划分为4个区域

  • 代码区:存放函数体的二进制代码,由操作系统进行管理的
  • 全局区:存放全局变量和静态变量以及常量
  • 栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
  • 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

内存四区意义: 不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程

什么是内存分区模型,分成了4个区,有什么用,分别说明每个区

内存分区模型是程序在运行时将内存划分为不同功能区域的机制,主要用于高效管理数据和代码的存储与访问。在大多数系统中,内存通常分为以下 4个核心区域,每个区域有明确的功能和特点:

1. 代码区(Text Segment)

  • 功能:存放可执行代码(如函数、类方法)和只读常量(如字符串常量)。
  • 特点
    • 只读(防止程序意外修改指令)。
    • 程序启动时由操作系统加载,生命周期与程序一致。
    • 共享性:多个进程运行同一程序时,可共享代码区。
  • 用途:确保指令安全、高效地执行。

2. 全局/静态区(Global/Static Segment)

  • 功能:存储全局变量静态变量(包括static修饰的局部变量)和常量数据(如全局const变量)。
  • 特点
    • 数据在程序启动时分配,程序结束时释放。
    • 未初始化的变量默认值为零(或空)。
    • 分为 已初始化区(如int a = 10;)和 未初始化区(如int b;)。
  • 用途:长期保存程序运行期间需要全局访问的数据。

3. 栈区(Stack Segment)

  • 功能:管理局部变量函数参数函数调用信息(如返回地址)。
  • 特点
    • 由编译器自动分配和释放(后进先出,LIFO)。
    • 空间有限(通常几MB),分配速度快。
    • 溢出风险:递归过深或局部变量过大时会导致栈溢出
  • 用途:高效支持函数调用和局部变量的生命周期管理。

4. 堆区(Heap Segment)

  • 功能:动态分配内存(如mallocnew申请的内存)。
  • 特点
    • 由程序员手动管理分配和释放(需用freedelete,否则内存泄漏)。
    • 空间大(受系统虚拟内存限制),但分配速度较慢。
    • 灵活性:适合存储大小不确定或生命周期长的数据。
  • 用途:支持程序运行时按需动态申请内存。

内存分区的作用

  1. 安全性:代码区只读防止指令被篡改,栈/堆隔离避免数据冲突。
  2. 效率:栈区快速分配释放,堆区灵活管理大内存。
  3. 资源管理:自动管理栈内存,减少程序员负担;堆区提供动态扩展能力。
  4. 共享性:代码区可被多进程共享,节省内存。

示例对比

分区
存储内容
生命周期
管理方式
大小限制
代码区
指令、只读常量
程序运行期间
系统自动
固定
全局/静态区
全局变量、静态变量
程序运行期间
系统自动
固定
栈区
局部变量、函数调用信息
函数执行期间
编译器自动
较小(MB级)
堆区
动态分配数据
手动释放前
程序员手动
大(GB级)

常见问题

  • 栈溢出:递归过深或定义超大局部数组(如int arr[1000000])。
  • 内存泄漏:堆区分配后未释放(如malloc后忘记free)。
  • 野指针:访问已释放的堆内存(需及时置空指针)。

理解内存分区模型有助于优化程序性能和排查内存相关错误(如崩溃、泄漏)。

New 和 Delete

以下是 new 和 delete 的经典用法代码示例,附带注释说明其操作逻辑及注意事项:

1. 基础用法:单个对象分配与释放

// 分配一个整型内存int* p = newint;   // 在堆上分配一个未初始化的 int 空间*p = 42;            // 写入数据delete p;           // 释放内存,p 变为悬空指针(建议后续置空:p = nullptr;)// 分配并初始化对象classMyClass {public:    MyClass(int val) : data(val) {}private:int data;};MyClass* obj = new MyClass(100);  // 调用构造函数分配并初始化delete obj;                        // 调用析构函数并释放内存

2. 数组分配与释放

// 分配整型数组int* arr = newint[5];   // 分配 5 个 int 的连续空间for (int i = 0; i < 5; i++) {    arr[i] = i * 10;}delete[] arr;            // 必须用 delete[] 释放数组// 分配对象数组MyClass* objs = new MyClass[3]{102030};  // 每个元素调用构造函数delete[] objs;                               // 对每个元素调用析构函数

3. 内存管理注意事项

// 错误示例 1: 内存泄漏(分配后未释放)voidleakMemory(){int* leak = newint(5);// 忘记 delete leak;}// 错误示例 2: 重复释放(导致崩溃)int* p = newint;delete p;delete p;  // 未定义行为(p 指向无效内存)// 正确做法: 释放后置空指针int* p = newint(10);delete p;p = nullptr;  // 防止误用悬空指针

4. 对比 new/delete 与 malloc/free

// malloc 不调用构造函数,free 不调用析构函数MyClass* m1 = (MyClass*)malloc(sizeof(MyClass));  // 对象未初始化free(m1);MyClass* m2 = new MyClass(50);  // 调用构造函数delete m2;                      // 调用析构函数

5. 动态对象的封装管理(RAII推荐)

#include<memory>// 使用智能指针替代裸 new/delete(C++11+)std::unique_ptr<MyClass> smartPtr = std::make_unique<MyClass>(200);// 无需手动 delete,智能指针自动释放内存

关键规则总结

  1. 配对使用new 对应 deletenew[] 对应 delete[],不可混用。
  2. 初始化优先:使用 new 时可以初始化(如 new int(10))。
  3. 避免悬空指针delete 后及时置空指针。
  4. RAII 原则:推荐使用智能指针(unique_ptr/shared_ptr)替代手动管理。

通过正确使用 new 和 delete,可以高效管理堆内存,但需时刻警惕 内存泄漏悬空指针 和 重复释放 等问题。

🔔 想要获取更多网络安全与编程技术干货?

关注 泷羽Sec-静安 公众号,与你一起探索前沿技术,分享实用的学习资源与工具。我们专注于深入分析,拒绝浮躁,只做最实用的技术分享!💻

扫描下方二维码,马上加入我们,共同成长!🌟

👉 长按或扫描二维码关注公众号

10x程序内存模型

或者直接回复文章中的关键词,获取更多技术资料与书单推荐!📚

原文始发于微信公众号(泷羽Sec-静安):10x程序内存模型

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月11日08:35:06
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   10x程序内存模型https://cn-sec.com/archives/3725320.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息