当前位置: 首页 > news >正文

内存分区

在程序运行时,操作系统会将内存划分为不同区域(分区),每个区域有特定的用途、生命周期和访问规则。

一、内存分区的整体结构

从低地址到高地址,内存通常分为以下几个区域:
代码区 → 常量区 → 全局/静态存储区 → 堆区 → 栈区 → 内核区
(注:不同系统的地址分布可能略有差异,但逻辑分区一致)
img

二、各分区的详细说明

1. 代码区

  • 用途:存储程序的机器指令(二进制代码),即编译后的可执行代码。

  • 特点:

    • 只读(防止程序意外修改指令),部分系统允许执行权限。
    • 编译时确定大小,程序运行期间不改变。
    • 共享性:多个进程运行同一程序时,可共享同一份代码区(节省内存)。
  • 示例:main函数、自定义函数的二进制指令都存放在这里。

2. 常量区

  • 用途:存储常量数据,包括字符串常量、const 修饰的全局常量等。
  • 特点:
    • 只读(修改会导致程序崩溃,如char* str = "hello"; str[0] = 'H'是错误的)。
    • 生命周期与程序一致(从程序启动到结束)。
  • 编译时确定大小,存储在可执行文件中。
const int MAX = 100;       // MAX存于常量区
char* str = "hello world"; // "hello world"字符串常量存于常量区,str是指针变量

3. 全局 / 静态存储区

  • 用途:存储全局变量和静态变量(包括static修饰的局部变量和全局变量)。
  • 细分:
    • 已初始化区(Data Segment):存储已初始化的全局 / 静态变量(如int a = 10; static int b = 20;)。
    • 未初始化区(BSS Segment):存储未初始化的全局 / 静态变量(如int c; static int d;),程序启动时会自动初始化为 0。
  • 特点:
    • 生命周期与程序一致(随程序启动而分配,结束而释放)。
    • 编译时确定大小,存储在可执行文件中(BSS 区仅记录变量名和大小,不占用文件空间)。
int g_var;               // 未初始化全局变量 → BSS区
static int s_var = 5;    // 已初始化静态变量 → Data区
void func() 
{static int ls_var;   // 未初始化局部静态变量 → BSS区(生命周期同程序)
}

4. 堆区

  • 用途:存储程序运行时动态分配的内存(如malloc/new申请的内存)。
  • 特点:
    • 动态分配:大小在程序运行时确定,需手动申请(malloc/new)和释放(free/delete)。
    • 地址增长方向:从低地址向高地址(与栈区相反)。
    • 无序性:多次分配和释放后会产生内存碎片。
    • 生命周期:由程序员控制,若未释放会导致内存泄漏(程序结束后由操作系统回收)。
int* p1 = (int*)malloc(4);   // 堆区分配4字节
int* p2 = new int[10];       // 堆区分配40字节(10个int)
free(p1);                    // 释放p1指向的堆内存
delete[] p2;                 // 释放p2指向的堆内存

5. 栈区

  • 用途:存储函数调用时的上下文信息,包括局部变量、函数参数、返回地址等。
  • 特点:
    • 自动管理:由编译器自动分配和释放(函数调用时分配,函数返回时释放)。
    • 地址增长方向:从高地址向低地址(与堆区相反)。
    • 大小固定:默认栈大小有限(通常几 MB),超出会导致栈溢出(Stack Overflow)。
    • 顺序性:遵循 “先进后出(FILO)” 原则,类似数据结构中的栈。
void func(int a) 
{int b = 10;  // a(参数)和b(局部变量)都存储在栈区
}
int main() 
{func(5);     // 调用func时,栈区为a、b分配空间;函数返回后自动释放return 0;
}

6. 内核区

  • 用途:操作系统内核代码和数据的专用区域,用户程序无法直接访问(受硬件保护)。
  • 特点:
    • 高地址区域,大小由操作系统决定(如 32 位系统通常划分 2GB 给内核区)。
    • 用于进程调度、内存管理、设备驱动等核心操作。

三、各分区的核心区别(对比表)

img

四、常见内存问题与分区的关系

  • 栈溢出:函数递归过深或局部变量过大(如int arr[100000];),超出栈区大小。
  • 内存泄漏:堆区内存未手动释放(如new后未delete),导致程序运行中可用内存逐渐减少。
  • 野指针:堆区内存释放后,指针未置空,后续访问可能操作已回收的内存(导致程序崩溃或数据错乱)。
  • 常量修改错误:试图修改常量区数据(如char* str = "abc"; str[0] = 'x'),会触发运行时错误。
http://www.hskmm.com/?act=detail&tid=29387

相关文章:

  • Spring Data JPA学习笔记
  • P1112 波浪数 题解
  • 20232411 2025-2026-1 《网络与系统攻防技术》实验一实验报告
  • 使用 Pascal 实现英文数字验证码识别系统
  • PWN手的成长之路-15-jarvisoj_level2_x64
  • 2025.10.12——1绿
  • 价值博弈场的工程实现:构建数字文明的价值免疫系统——声明Ai生成
  • 基于 Rust 的英文数字验证码识别系统设计与实现
  • 2025年两联供室内机厂家最新权威推荐榜:技术实力与市场口碑
  • 2025武汉商铺装修防水厂家最新权威推荐榜:专业施工与品质保
  • 2025铝合金微弧氧化厂家权威推荐榜:表面处理技术实力深度解
  • 2025杉木木方厂家最新权威推荐榜:优质木材与稳定供应口碑之
  • 2025年厂房保养厂家最新权威推荐榜:专业维护与成本控制优选
  • 使用C语言实现重写stm32的启动文件
  • 2025中医师承权威推荐榜:名师带徒与临床实践深度解析
  • 让我们开始 CSS 的学习之旅
  • 2025液压无损扒胎机厂家权威推荐榜:高效无损与耐用性能深度
  • Linux环境下的UDEV机制及其与守护进程的关联
  • 在Red Hat Enterprise Linux 9上使用Docker快速安装并部署
  • [转] 基于ubuntu-base进行根文件系统的修改与打包
  • jquery 字符串转数字
  • AI圈每日技术学习---紧跟时代脚步(N8n工作流)
  • B -识别浮点常量问题
  • 小C语言--词法分析程序-A
  • 查寻MySQL或SQL Server的连接数,并配置超时时间和最大连接量
  • 2025宿舍上下床厂家权威推荐榜:耐用设计与空间优化口碑之选
  • 梳理一下Java中为保证线程安全提供了那些方案 - 浪矢
  • 处理Git错误:“invalid object [hash]”和“unable to read tree [hash]”
  • 2025厂房恒温恒湿设备厂家权威推荐榜:精准控温与节能技术深
  • 面向对象编程实验一