裸数组初始化必须按场景选语法:局部内置数组用{}确保零初始化,std::array需显式指定大小,new[]须加()才清零,字符数组要预留'\0'空间。

裸数组初始化不是“选一种写法就行”,而是不同场景下必须用对语法,否则轻则值未定义,重则编译失败或跨平台行为不一致。
局部内置数组用 {} 初始化最稳妥
局部变量数组不初始化就是栈上随机值,读取即未定义行为。用空大括号 {} 能确保全部元素为 0,且兼容所有 C++ 标准:
-
int arr[5] = {};→ 所有 5 个int都是 0 -
int arr[5] = {42};→arr[0]是 42,其余 4 个是 0 -
int arr[5] = {1, 2};→arr[0]=1,arr[1]=2,arr[2]~arr[4]= 0 - 别写
int arr[5];然后直接用 —— 局部数组不会自动清零
std::array 必须显式指定大小,不能靠推导
std::array 是类型安全替代品,但模板参数里的长度不能省;漏写会编译失败,不是警告:
- ✅ 正确:
std::array<int> a = {1, 2, 3};</int>或std::array<int> a{1, 2, 3};</int> - ❌ 错误:
std::array<int> a = {1, 2, 3};</int>—— 缺少长度模板参数,GCC/Clang 都报错 - ⚠️ 注意:
std::array<int> a{};</int>等效于全零初始化,但不是靠“推导”,而是值初始化语义
动态数组 new int[N] 不加 () 就是垃圾值
很多人以为 new int[10] 至少会清零,其实完全不会 —— 它只分配内存,不调用初始化:
立即学习“C++免费学习笔记(深入)”;
- ❌ 危险:
int* p = new int[10];→ 所有元素值未定义,哪怕只读p[0]也是 UB - ✅ 安全:
int* p = new int[10]();→ 括号()触发值初始化,全部为 0 - ✅ 可选:
int* p = new int[10]{1, 2};→ 前两个为 1/2,其余为 0(C++11 起) - 别忘了配对
delete[] p;,用delete p会 UB
字符数组初始化要算上 '\0' 的位置
用字符串字面量初始化 char[] 时,编译器自动把末尾 '\0' 当作一个元素,这点极易踩坑:
- ✅ 合法:
char s[6] = "hello";→"hello"是 5 字符 +'\0'= 6 字节 - ❌ 编译失败:
char s[5] = "hello";→ 没空间放'\0',Clang/GCC 均拒编译 - ✅ 安全写法:
char s[] = "hello";→ 编译器自动算出长度为 6 - ⚠️ 若后续要传给
strlen()或printf("%s"),没'\0'就会越界读内存
最容易被忽略的是:裸数组的初始化行为高度依赖存储期(局部/全局/static)和括号有无,而这些差异在高优化级别(如 -O2)下可能让 bug 隐蔽得极深 —— 比如局部 int buf[1024]; 在调试时看似是 0,上线后突然崩,大概率就是忘了初始化。


















