C 内存属性

五大内存分区

  1. 代码段(Text /.text 段)
    ● 存放:CPU 指令、函数汇编代码、跳转表
    ● 权限:读 R、执行 X,不可写 W
    ● 特点:程序加载时载入;尝试写入直接触发0xC0000005访问违例
  2. 数据段(.data)
    ● 存放:已经初始化的全局变量、static 静态变量
    ● 权限:可读、可写,不可执行
    ● 补充:字符串常量很多放在.rdata只读数据段(不属于.text,同样只读)
  3. BSS 段(.bss)
    ● 存放:未初始化的全局变量、static 静态变量
    ● 特点:程序运行前操作系统统一清零;PE 文件里不占用磁盘空间,加载到内存才分配
  4. 堆(Heap)
    ● 存放:malloc / calloc / realloc动态申请内存
    ● 管理:手动申请、手动 free 释放,忘记释放造成内存泄漏
    ● 用途:动态数组、链表、自定义结构体
  5. 栈(Stack)
    ● 存放:局部变量、函数参数、返回地址、ebp 栈帧
    ● 管理:自动分配自动回收,函数退出直接释放栈帧
    ● 限制:栈容量很小,无限递归 / 大局部数组 → 栈溢出 Stack Overflow

例题解析

  1. 全局、局部变量地址分布
c 复制代码
int g_num1 = 10;   // .data段
int g_num2[100];   // .bss段
int main(void)
{
    int a = 10;    // 栈
    int b;         // 栈
    char* str = "0xCC"; // "0xCC"字符串常量放在只读rdata段
    return 0;
}

● str本身变量在栈,*str指向只读数据段

  1. 递归与栈溢出 每次递归调用都会新建栈帧,保存返回地址 + 局部变量

无终止条件 → 栈不断增长,耗尽栈空间 → Stack Overflow 崩溃

  1. CE 调试查看内存权限 进程加载后,每个内存页标记属性:R/W/X

● 代码段:R+X,禁止写,防代码注入

● 栈:默认无执行权限(DEP 保护)

● 堆:默认 R/W,无执行

内存权限实践代码

c 复制代码
#include <stdio.h>
int g_data = 100;       // .data
int g_bss[200];         // .bss
int main()
{
    int stack_var = 20; // 栈
    char* str = "hello";// str指针在栈;字符串常量在只读rdata
    printf("栈变量地址:%p\n", &stack_var);
    printf("data全局变量:%p\n", &g_data);
    printf("bss全局数组:%p\n", &g_bss);
    printf("字符串常量地址:%p\n", str);
    return 0;
}

总结

  1. 只读字符串常量不在 data 段,在.rdata只读数据段,修改会崩溃
  2. static 静态变量,无论写在函数内部还是全局,都归属.data/.bss,不在栈
  3. 栈内存自动回收,但不清理旧数据,容易产生脏数据
  4. BSS 段在 PE 文件不占磁盘大小,加载到内存才分配并清零
相关推荐
Zwawa1 小时前
一盏 LED 不够用了:让同一盏灯说出不同的话
c语言·单片机·嵌入式
lengxuenong1 小时前
树状数组 · 信息学学习手册1-求和3个模板
c++·学习·算法·青少年编程
ComputerInBook1 小时前
泛函分析概观
人工智能·算法·机器学习·泛函分析
万联WANFLOW2 小时前
让分散的设备像在同一张局域网里:企业组网技术解析
运维·网络·网络安全·智能路由器
Nuanyt2 小时前
LeetCode Hot100 刷题笔记 · 普通数组专题
java·笔记·算法·leetcode
q27551300422 小时前
AS8132 DP转HDMI 4K60(420)被动式 国产性价比AS方案
linux·算法·硬件架构·dash
安全指北针2 小时前
密态计算:数据 “可用不可见” 的底层技术解析
人工智能·算法
Jmyd01232 小时前
3D 扫描仪选型技术拆解:精度、点云与软件链路
人工智能·算法·3d·三维数字化