<p>传指针时函数内修改不生效是因为C++按值传递指针副本;想改指针本身需传int&或int;const int限制改值,int* const限制改指向;裸指针易致空解引用崩溃,应优先用span或智能指针。</p>

传指针时为什么函数内修改不生效
常见现象是:在函数里对 int* 指针做 ptr = new int(42),调用后原指针仍为 nullptr 或旧地址。这是因为 C++ 默认按值传递——传进去的是指针变量的副本,改副本不影响原始指针变量本身。
真正想修改指针所指向的值(比如 *ptr = 100),没问题;但想让调用方的指针变量指向新地址,就必须传指针的引用或二级指针。
- 想改指针指向的值 → 传
int*即可 - 想改指针变量本身(让它指向别处)→ 传
int*&或int** - 传
int**时,调用方要传&ptr,函数内用*pptr = new int(42)
用 int*& 改变原始指针更简洁
相比二级指针,引用形式语义更清晰、调用更干净,避免多层解引用出错。尤其适合资源分配类函数,比如初始化一个动态数组并返回首地址。
void create_buffer(int*& buf, size_t n) {
delete[] buf; // 安全起见先释放旧内存
buf = new int[n]{}; // 分配并零初始化
}调用:int* p = nullptr; → create_buffer(p, 10); → 此时 p 已指向新内存。
立即学习“C++免费学习笔记(深入)”;
注意:如果函数可能不修改指针(只读访问),就不要用引用传参,否则会误导调用者以为“一定会改”。
传 const int* 和 int* const 的区别常被搞混
前者限制“不能通过该指针改所指内容”,后者限制“不能让该指针指向别处”。两者控制维度不同,选错会导致编译失败或逻辑漏洞。
-
void f(const int* p):允许p++,禁止*p = 5 -
void f(int* const p):禁止p = &x,允许*p = 5 -
void f(const int* const p):两者都不允许
实际中,只读访问数据时优先用 const int*;若函数内部需移动指针遍历(如字符串处理),又不想意外改指向,才考虑 int* const。
裸指针传参在现代 C++ 中容易踩内存安全坑
传 int* 本身不报错,但调用方可能传 nullptr,函数里忘了判空就直接解引用,导致崩溃。RAII 和智能指针不是银弹,但至少能减少这类问题。
- 如果函数必须拥有资源所有权,考虑传
std::unique_ptr<int>&&</int> - 如果只是临时访问,优先用
span<const int>(C++20)或gsl::span替代裸指针 - 必须用裸指针时,文档和函数名要明确是否接受
nullptr,并在入口加assert(ptr != nullptr)或显式判空
裸指针传参不是不能用,而是它把责任完全推给调用方和实现者——稍一松懈,segmentation fault 就在下一行等着。


















