函数参数需声明为T*&才能修改指针本身,调用时直接传指针变量名;若管理动态内存,应优先使用std::unique_ptr&以避免泄漏和手动释放风险。

函数参数声明要写成 T*& 而不是 T*
想在函数里修改指针本身(比如让它指向新地址),必须传指针的引用。只传 T* 是传值,函数内对指针变量的赋值不会影响调用方的原始指针。
常见错误是写成 void func(int* p) 然后在函数里写 p = new int(42);——这只会改局部副本,调用方的指针依然为 nullptr 或原值。
-
T*&表示“指向T的指针的引用”,能真正绑定到调用方的指针变量 - 声明时
&紧贴类型名或变量名都合法,但推荐int*& ptr形式,强调“引用的是指针” - 不能传字面量或临时表达式(如
func(&x)是错的,因为&x是右值)
调用时直接传指针变量名,不加 &
既然参数是引用,调用时就和普通引用一样:传变量名本身,不是取地址。加 & 反而会变成传指针的地址(即 int**),类型不匹配。
典型错误:把 int* p = nullptr; 传给 void init(int*& ptr) 时写成 init(&p)——编译失败,因为 &p 类型是 int**。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 正确写法:
init(p); - 如果函数声明是
void init(int** ptr),才需要init(&p),但那是双重间接,语义不同 - 引用传递不涉及额外解引用开销,和传指针值一样高效
注意空指针和内存泄漏风险
通过引用修改指针后,旧指向的资源容易被遗忘。尤其当原指针非空时,直接赋新地址会导致内存泄漏。
例如:int* p = new int(1); init(p); 若 init 内部执行 ptr = new int(2);,原 new int(1) 就泄露了。
- 函数职责要明确:是初始化、重分配,还是交换?最好在命名或注释里体现
- 若需释放旧资源,应在函数内显式
delete(或更推荐用std::unique_ptr) - C++11 后优先考虑智能指针,
void init(std::unique_ptr<int>& ptr)</int>更安全
和 std::unique_ptr 引用传参对比
如果你实际想管理动态内存,用裸指针引用反而增加出错概率。现代 C++ 中,std::unique_ptr<t>&</t> 是更自然的选择。
它既能转移所有权(通过 std::move),也能重置(ptr.reset(new T)),且自动析构,避免手写 delete 的疏漏。
-
void load_data(std::unique_ptr<int>& ptr)</int>可以安全地ptr = std::make_unique<int>(42);</int> - 裸指针引用适合底层接口、与 C 兼容场景,或明确不涉及内存管理的指针操作(如遍历链表时更新 head)
- 混合使用裸指针引用和智能指针需格外小心:别把
std::unique_ptr.get()的结果存作长期裸指针
函数里改指针本身这事,核心就两点:声明写对 T*&,调用传对变量名。难的不是语法,是想清楚谁负责释放、什么时候释放、有没有隐式生命周期依赖。

















