因为c++按值传递指针,函数内修改副本不影响原指针;可行方案:①二级指针、②指针引用(推荐)、③返回新指针;需注意内存泄漏、类型安全拷贝及异常安全。

为什么直接传指针无法在函数内重新分配数组
因为 C++ 默认按值传递参数,int* arr 传进函数时,函数内部只是拿到了原指针的副本。你在函数里对这个副本执行 new 或 realloc,只改了副本指向的地址,原指针变量本身完全没变——外部调用者看到的还是旧地址,甚至可能变成悬空指针。
三种可行方案及适用场景
核心思路是让函数能修改“指针变量本身”,而非它指向的内容:
-
用二级指针:最直接,适合 C 风格或需要兼容 C 的场景。
函数声明为void resize_array(int** arr, size_t new_size),调用时传&ptr,内部用*arr = new int[new_size]。 -
用引用传指针:C++ 推荐方式,语义清晰,避免裸指针误操作。
声明为void resize_array(int*& arr, size_t new_size),调用时直接传ptr,内部写arr = new int[new_size]即可。 -
返回新指针:更函数式,调用方显式接收结果,不易遗漏赋值。
声明为int* resize_array(int* arr, size_t old_size, size_t new_size),内部delete[] arr后return new int[new_size];调用方必须写ptr = resize_array(ptr, ...)。
容易踩的坑:内存泄漏和越界访问
重分配不是简单 new 就完事,关键逻辑常被忽略:
- 旧数组非空才
delete[],否则delete[] nullptr虽安全但掩盖逻辑缺陷; - 拷贝数据时别用
memcpy直接搬原始字节——如果数组元素是带构造函数的类类型,必须逐个调用拷贝构造; - 若用
std::vector替代裸指针,resize()或assign()自动处理所有细节,且异常安全; - 重分配失败(
new抛std::bad_alloc)时,原指针不能丢失——推荐先new再delete[],或用std::unique_ptr管理中间状态。
示例:安全的引用传参重分配
void safe_realloc(int*& arr, size_t old_size, size_t new_size) {
if (new_size == 0) {
delete[] arr;
arr = nullptr;
return;
}
int* new_arr = new int[new_size]; // 可能抛异常
size_t copy_len = std::min(old_size, new_size);
for (size_t i = 0; i <p>调用:<code>int* p = new int[3]{1,2,3}; safe_realloc(p, 3, 5);</code> —— 此后 <code>p</code> 指向新数组,旧内存已释放。</p><p>真正麻烦的从来不是语法怎么写,而是谁负责释放、何时释放、异常发生时是否还能保证资源不泄露——裸指针重分配把这三个问题全摊在调用者面前,稍不注意就埋下崩溃或泄漏的种子。</p>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











