C_内存 内存地址概念

1. 计算机内存的基本概念

计算机的内存(RAM,随机存取存储器)是用来存储程序运行时的数据和指令的地方。**内存被划分为许多小单元,每个单元有一个唯一的地址,**这些地址从0开始编号。

  • 内存单元:每个内存单元通常是一个字节(8位),用来存储一个字符或部分整数。
  • 内存地址 :每个内存单元都有一个唯一的地址,用于标识它。例如,地址0x1000表示内存中某个特定位置。

2. C语言中的内存模型

C语言中的内存可以大致分为以下几个区域:

(1)代码区(Text Segment)

  • 存储程序的机器指令(即编译后的代码)。
  • 这部分内存是只读的,防止程序意外修改自己的指令。

(2)全局/静态区(Data Segment)

  • 存储全局变量和静态变量。
  • 又分为两部分:
  • 初始化数据区:存储已初始化的全局变量和静态变量。
  • 未初始化数据区(BSS段):存储未初始化的全局变量和静态变量。

(3)堆区(Heap)

  • 用于动态内存分配(如malloccallocrealloc等函数分配的内存)。
  • 程序员需要手动管理堆区的内存分配和释放(使用free函数)。
  • 堆的大小不固定,可以根据需要增长。

(4)栈区(Stack)

  • 用于存储函数调用时的局部变量、函数参数、返回地址等。
  • 栈的大小是固定的,通常较小。
  • 栈是自动管理的,当函数调用结束时,栈上的局部变量会自动销毁。

3. 指针与内存地址的关系

指针是C语言中直接操作内存的核心工具。指针本质上是一个变量,它存储的是另一个变量的内存地址。

(1)指针的基本概念

  • 指针变量本身占用内存空间(通常是4字节或8字节,取决于系统架构)。
  • 指针变量的值是一个内存地址。

(2)指针与内存地址的关系

4.通过*解引用指针p,可以直接访问和修改变量a存储在内存中的数值(数据内容),只是改变了该变量a在内存地址中存储的数据内容,而变量a的内存地址本身是保持不变的。

(1)变量在内存中的内存地址 vs 存储值的关系

变量在内存中的内存地址

  • 每个变量在声明时 系统为变量分配了一块内存空间, 这块内存空间有一个唯一的固定的地址(0000007BF96FF5D4) 在变量的生命周期内该内存中地址是固定不变的,不会因为值的变化而改变。并且在这块内存空间(也可以叫这个对应的内存地址上)中存储了变量的初始值(比如10)。
  • 内存地址是用来标识变量在内存中的位置。每个变量在内存中都有一个唯一的内存地址。
  • 而存储的数值是该"位置"编号中存放的内容。
  • 修改这个变量的数值并不会改变该变量的内存地址编号。

存储的值

  • 内存地址对应的存储单元中存放的具体数据。对于变量a来说,存储值就是10
  • 可以通过直接访问变量或通过指针解引用来修改。

图解说明

(2)示例代码

cpp 复制代码
  /*
 
 系统为变量a2分配了一块内存空间, 这块内存空间有一个唯一的地址(0000007BF96FF5D4),并且在这块内存(也可以叫这个对应的内存地址上)中存储了变量的初始值(比如10)。
 
*/
  int a2 = 10;  // 声明并初始化变量a
  int* p_a2 = &a2;  // 定义一个指针p,指向变量a2的地址

  // 打印初始状态 
  printf("变量2a的初始值=%d\n", a2);  //变量2a的初始值=10
   printf("变量a2在内存中的内存地址编号=%p\n", (void*)&a2); //变量a2在内存中的内存地址编号=0000007BF96FF5D4

  //通过*解引用指针p,可以直接访问和修改变量a2   存储在内存地址 (0000007BF96FF5D4)上对应的数值(数据内容)从10改为20,此时的内存地址没有变,但该内存地址上存储的值已经变为20
   
   * p = 20;  // 相当于 a2 = 20;

 // 打印修改后的状态
    printf("变量a2的修改后值=%d\n", a2);  //变量a2的修改后值=10
    printf("变量a2在内存中的地址编号=%p\n", (void*)&a2); //变量a2在内存中的地址编号=0000007BF96FF5D4

(3)通过以上实例代码,为什么内存地址不变?

  • 变量在内存里的内存地址是由编译器和操作系统在程序运行时分配的,并且在变量的生命周期内是固定不变的。
  • 修改值只会影响内存里单元中的内容(数值),而不会改变变量本身的在内存里的内存地址。

内存地址是变量的位置标识,而值是该位置中存储的内容。修改值只是改变了内容,而位置本身不会发生变化。

相关推荐
职场的momo1 分钟前
11个后端与AI岗位同时开放:Java、网关、推理优化怎么匹配
java·开发语言·人工智能
蓝速科技6 分钟前
蓝速科技丨新旧楼宇混杂场景下会议室预约门牌屏一体化改造方案
开发语言·科技·php
梦想的旅途21 小时前
Python实现企业微信文本消息发送
开发语言·python·企业微信
大鹏说大话1 小时前
美业微信会员系统哪个好
开发语言
程序员与背包客_CoderZ2 小时前
高性能分布式KV存储引擎RocksDB入门与C/C++编码实战
c语言·开发语言·数据库·c++·分布式·分布式数据库·rocksdb
钱栈up2 小时前
Mac 开发机一键发版不用切环境:我这样改造了团队的后端部署脚本Maven编译卡住20分钟?我靠两步定位到2处隐蔽编译错误
开发语言·python·macos
william_yangshun2 小时前
【大模型部署实战】kimi-k3-in-c 中文版:用 176KB 纯 C99 引擎在 CPU 上跑 Kimi K3 上手指南
c语言·开发语言
Sagittarius_A*3 小时前
Burst Lab | PHP 审计 14|反序列化(四):字符串逃逸与绕过技巧
开发语言·安全·php·web·反序列化
名字还没想好☜3 小时前
Go 用 slices/maps 标准库泛型函数:告别手写 Contains、Sort、去重(Go 1.21)
开发语言·后端·算法·golang·go
淼澄研学3 小时前
Python实战:基于LangChain与Chroma构建企业级RAG知识库问答系统
开发语言·python·langchain