栈数组由编译器自动管理、大小固定且作用域结束即销毁;堆数组需手动用new[]/delete[]管理、大小运行时决定但易致内存泄漏或碎片;std::vector栈上存控制块、数据在堆上,兼顾安全与灵活性。

栈数组和堆数组在 C++ 中根本不是同一类东西:一个靠编译器自动管理,一个靠程序员手动扛责任。选错地方,轻则程序崩溃,重则内存泄漏长期潜伏。
栈数组:大小固定、作用域结束就消失
栈数组必须在编译期就知道大小,声明即分配,函数返回或作用域结束时自动销毁,不用 delete,也不用担心泄漏。
-
int arr[100]是合法的;int n = 100; int arr[n]在标准 C++(C++14 及以后)中是非法的(除非开启 GNU 扩展),因为n不是常量表达式 - 数组名
arr是栈上连续内存块的首地址,类型是int[100],不能直接赋值给int*(但会隐式转换) - 栈空间小(通常几 MB),
int big[1000000]极易触发stack overflow,尤其在递归或嵌套调用深的场景 - 栈数组内容未初始化(值为垃圾),
int arr[5]的每个元素值不确定;想清零得写int arr[5] = {}或int arr[5]{}
堆数组:大小运行时决定、必须手动释放
堆数组用 new[] 分配,用 delete[] 释放,生命周期完全由你控制,但漏掉 [] 或配对错误会导致未定义行为。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
int* p = new int[n]合法,n可以是变量、函数返回值、用户输入——这是栈做不到的 - 必须用
delete[] p,不能用delete p;前者调用每个元素的析构(对类数组重要),后者只调用第一个元素析构并破坏内存管理元数据 -
p本身是栈上的指针变量,它指向的那块连续内存才在堆上;p消失不等于堆内存释放 - 频繁
new[]/delete[]容易产生内存碎片,尤其在长期运行的嵌入式或机器人程序中,可能让后续大块分配失败
std::vector 是什么?它不是“栈数组”也不是“堆数组”
std::vector 对象本体(含容量、大小、指针成员)在栈上,但它内部管理的元素数组一定在堆上。它帮你做了 new[]/delete[] 和异常安全处理,但代价是每次扩容要重新分配+拷贝。
立即学习“C++免费学习笔记(深入)”;
- 写
std::vector<int> v(1000)</int>,等价于在堆上分配 1000 个int,栈上只存一个 24 字节(典型)的vector控制块 - 不要误以为
vector是“栈优化”——它的数据永远不在栈;只是比裸new[]更安全、更灵活 - 如果确定大小且永不改变、性能极致敏感(比如实时控制循环里),裸栈数组
int buf[256]仍比vector少一次间接寻址和分支判断
最易被忽略的是:栈数组的“固定大小”不只是语法限制,更是编译器生成栈帧时的硬约束;而堆数组的“动态”背后是操作系统堆管理器查链表、拆分块、填元数据——这些开销在毫秒级响应要求的机器人控制逻辑里,真的会被测出来。

















