动态数组扩容本质是创建新空间、搬数据、换指针;Java用System.arraycopy精确复制或Arrays.copyOf便捷扩容,C++用std::copy/memmove安全迁移,均不采用realloc因其破坏对象语义和内存安全。

动态数组扩容不是“给原数组加空间”,而是创建新空间、搬数据、换指针的过程。系统函数的作用,是把“搬数据”这一步做得更安全、更高效,而不是绕过内存重新分配本身。
Java中用System.arraycopy迁移数据
这是最底层、最可控的数组复制方式,适合需要精确控制起始位置和长度的场景。
- 语法结构:`System.arraycopy(源数组, 源起始索引, 目标数组, 目标起始索引, 复制元素个数)`
- 关键约束:目标数组必须已存在且足够大;类型必须兼容;不检查运行时类型(如Object[]拷贝到String[]会抛ArrayStoreException)
-
实用示例:将长度为5的int数组扩容到8,只需
int[] old = {1,2,3,4,5};<br> int[] newarr = new int[8];<br> System.arraycopy(old, 0, newarr, 0, old.length); // 复制全部5个元素
Java中用Arrays.copyOf快速扩容
这是对arraycopy的封装,一行代码完成“新建+复制”,适合常规扩容需求。
- 本质行为:内部调用System.arraycopy,但自动处理新数组创建逻辑
-
常用重载:
Arrays.copyOf(original, newLength)—— 类型由original推导,新数组用默认值填充多余位置 - 注意点:newLength可以小于原数组长度,此时只取前newLength个元素;若大于,则末尾补零(数值型)或null(引用型)
C++中用std::copy或memmove做迁移
在手动管理动态数组时,避免用原始for循环逐个赋值,改用标准库迁移函数更安全、可读性更高。
-
std::copy:适用于支持拷贝构造/赋值的类型,语义清晰,推荐用于类对象数组
std::copy(oldData, oldData + size, newData); -
memmove:适用于POD类型(如int、char*),按字节搬运,效率略高,且能安全处理内存重叠
memmove(newData, oldData, size * sizeof(T)); - 迁移后必须delete[] oldData,否则内存泄漏;同时更新指针和capacity变量
为什么不用realloc?
虽然C语言的realloc看起来“一键扩容”,但它有隐含风险:
- 失败时返回NULL,原指针仍有效——若忘记检查,直接赋值会导致内存丢失
- 成功时可能移动内存,原有指针失效,而C++对象需调用析构/构造,realloc无法触发这些语义
- Java和C++标准库均不采用realloc,因其与面向对象内存模型不兼容

















