指针数组正确声明为类型 数组名[大小],如int p_arr[3];需初始化避免悬空指针,存字符串时注意字面量只读性,优先用std::array等智能容器管理内存。

指针数组的声明语法容易写反
很多人把 int* arr[5] 错写成 int arr*[5] 或 int* [5] arr,编译直接报错。关键在于:方括号紧跟变量名,星号属于元素类型的一部分。
正确形式是 类型* 数组名[大小],表示“一个长度为 N 的数组,每个元素都是指向该类型的指针”。
-
int* p_arr[3];—— 合法:含 3 个int*元素的数组 -
int (*p_arr)[3];—— 这是数组指针(指向含 3 个int的数组),不是指针数组 -
int** p_arr[3];—— 合法:含 3 个int**元素的数组(即指向指针的指针数组)
初始化指针数组要避免悬空指针
声明后若不初始化,数组中每个指针都是未定义值,解引用必崩溃。常见做法是初始化为 nullptr,或直接绑定已有变量地址。
int a = 10, b = 20, c = 30;
int* p_arr[3] = {&a, &b, &c}; // OK:直接初始化
// 或
int* q_arr[3] = {nullptr}; // OK:零初始化(C++11 起支持聚合初始化为 nullptr)
// 但注意:
int* r_arr[3];
// r_arr[0] 此时是垃圾值,不能用 *r_arr[0]
用指针数组存字符串要注意内存来源
用 char* 数组存字符串字面量最常见,但必须清楚:字面量存在只读区,不能修改;若需修改,得用 char[] 或 std::string。
-
const char* str_arr[2] = {"hello", "world"};—— 安全,推荐加const -
char* str_arr[2] = {"hello", "world"};—— 编译可能警告(弃用转换),运行时修改会段错误 -
char buf1[] = "hello"; char buf2[] = "world"; char* str_arr[2] = {buf1, buf2};—— 可修改,但注意作用域(别返回局部数组地址)
和 std::array<:unique_ptr>, N> 对比时别忽略所有权
原始指针数组不管理内存,new 出来的对象必须手动 delete,否则泄漏。现代 C++ 更推荐:
#include <memory> #include <array> std::array<:unique_ptr>, 3> smart_arr; smart_arr[0] = std::make_unique<int>(42); // 自动释放</int></:unique_ptr></array></memory>
但若要兼容 C 接口、做底层操作或性能敏感场景,原始指针数组仍有不可替代性——只是得自己扛住生命周期责任。
最容易被忽略的是:指针数组本身是栈对象,但里面存的地址可能指向堆、静态区或栈,每种情况的生存期规则完全不同,混用时尤其容易踩坑。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











