## 今天学了什么
今天学习C++的内存四区模型,以及new/delete的基本用法。
## 内存四区总结

备注:其中代码区和全局区处于程序运行前,栈区和堆区处于程序运行后。
内存四区的意义:不同区域存放的数据赋予不同的生命周期,方便管理、灵活编程。
**实测地址(Windows 64位 + VS)**:
– 全局变量 `global_a` 地址:00007FF6026BF000
– 栈区变量 `a` 地址:00000091057CF704
– 堆区 `new_a` 地址:0000026D4C157E10
## 今日代码
```cpp
#include<iostream>
using namespace std;
//全局区
//全局变量
int global_a = 10;
//静态变量
static int static_a = 1;
//常量 const修饰常量、字符串常量
const int const_a = 2;
//栈区
//局部变量
int fun(int local_a)
{
cout << "形参local_a的地址:" << &local_a << endl;
return local_a;
}
//堆区
int * creatNum()
{
int* p = new int(666);
return p;
}
int main()
{
static int static_b = 2;
//const char *char_a = "hello world";
int* new_a = creatNum();
int* pp = new int[2];
int a = 9;
//cout << a<<endl;
for (int i = 0; i <2; i++)
{
pp[i] = i + 1;
}
for (int i = 0; i < 2; i++)
{
cout << pp[i]<<endl;
}
int b = 5;
cout << "全局变量global_a的地址:" << &global_a << endl;
cout << "静态变量static_a的地址:" << &static_a << endl;
cout << "静态变量static_b的地址:" << &static_b << endl;
cout << "const修饰常量const_a的地址:" << &const_a<< endl;
cout << "字符串常量的地址:" << &"hello world" << endl;
cout << endl;
cout << "局部变量量a的地址:" << &a << endl;
cout << "局部变量量b的地址:" << &b << endl;
fun(3);
cout << endl;
cout << "堆区数据地址:" << new_a << endl;
cout << "堆区指针数组的首元素地址:" << pp << endl;
/*delete new_a;
new_a = nullptr;*/
delete[] pp;
pp = nullptr;
return 0;
}
运行结果:

## 逐步调试步骤
1.打断点 鼠标点击左边灰色栏对应行
2.按F5进入调试
3.F10/F11逐行调试,F10会直接跳过函数(F10逐过程 F11逐语句)
调试-窗口-局部变量 观察各个变量值的变化
## 问题记录
**内存泄漏实验**:在写int * p=new int(5);时,故意不写delete p;结果正常运行,什么异常也没有发现,进入逐步调试,只能看到在程序结束时,p的值还存在。
结论:内存泄漏在程序结束时看不出来,但如果长期运行程序,内存会一直涨,最终崩溃。
**指针、地址、解引用**:
```cpp
int a=10;
int * p=&a; //指针p的值是a的地址 int * : 整型指针
cout<<*p; //*p 解引用,输出a的值 输出结果:10
## 深度思考:为什么打印的地址是负数?
第一次运行时,发现输出的地址是负数。查了资料才知道:
– 用 `int` 去接收地址(比如 `(int)&a`),但 `int` 只有 32 位
– 我的环境是 64 位,地址是 64 位十六进制数
– 把 64 位地址强行塞进 32 位 `int`,高 32 位被截断,剩下的最高位如果是 1,就变成负数
– 教程里老师没遇到这个问题,是因为他用的是 32 位程序,地址数值小,不会溢出
**正确做法**:直接用 `cout` 输出指针,或者转成 `uint64_t`。
## 深度思考:堆区和栈区谁的地址高?
实测发现:Windows 64位 + VS 环境下,**堆区地址比栈区地址大**。这和很多教程里“栈在顶部、堆在底部”的说法不一样。
查资料得知:堆和栈的地址顺序取决于操作系统和编译器,没有统一标准。所以不要背“谁高谁低”,记住它们的管理方式区别就行了。
** 学习堆区的作用 **
知道数据存在哪,什么时候消失,提前避开崩溃、内存泄漏这些bug,写程序的时候判断放在栈还是堆。
** 野指针的危害 **
- 读取乱码,奇怪负数
- 程序闪退随机崩溃,很难复现排查
- 严重时会篡改别的变量,产生莫名其妙的错误
![打卡信奥刷题(3584)用C++实现信奥题 P11523 [THUPC 2025 初赛] 摊位分配-171主机测评](https://www.171host.com/wp-content/uploads/2026/09/20260922020544-6ab1e2783b78e-220x150.png)


