c++怎么给数组动态扩容_c++模拟动态数组【技巧】

1次阅读

new[] 配合手动 realloc 是最直接的扩容方式;需申请新内存、复制旧数据、释放旧内存,注意检查 nullptr、更新长度、避免悬空指针,并按 1.5× 或 2× 增长以减少频繁分配。

c++怎么给数组动态扩容_c++模拟动态数组【技巧】

new[] 配合手动 realloc 是最直接的扩容方式

new[] 分配原始数组后,c++ 没有内置“扩容”操作;必须申请新内存、复制旧数据、释放旧内存。这不是语法糖,是显式内存管理的必然步骤。

常见错误现象:std::bad_alloc(申请失败)、越界读写(忘了更新长度变量)、悬空指针(释放后还用原指针)。

  • 每次扩容建议按 1.5× 或 2× 增长,避免频繁分配(如从 10 扩到 11,性能极差)
  • 复制必须用 std::memcpy循环赋值,不能直接 operator=(原生数组不支持)
  • 务必检查 new 是否返回 nullptr(尤其在异常禁用时)

示例:把 arrsize 扩到 new_size

int* new_arr = new int[new_size]; std::memcpy(new_arr, arr, size * sizeof(int)); delete[] arr; arr = new_arr;

vector 是唯一推荐的“动态数组”替代方案

手写扩容逻辑极易出错,且无法自动处理构造/析构(比如 std::String 成员)。除非嵌入式场景明确禁用 STL,否则直接用 std::vector

立即学习C++免费学习笔记(深入)”;

使用场景:需要 push/pop、随机访问、跨函数传递、含非 POD 类型的容器。

  • std::vector::reserve() 只改容量不改大小,不会触发元素构造
  • std::vector::resize() 改大小,会默认构造新增元素(对 int 是 0,对 string 是空串)
  • 迭代器失效:push_back 可能导致所有迭代器失效(扩容时)

别用 vector.data() 后长期持有指针——扩容后地址就变了。

realloc 不适用于 C++ 对象数组

realloc 是 C 函数,只做内存块搬移,**完全跳过构造和析构函数调用**。对 std::stringstd::vector 等类型,会导致资源泄漏或二次析构崩溃。

错误现象:double free or corruptionsegmentation fault字符串内容乱码。

  • 仅当数组元素是 POD 类型(如 intFloat、纯 C Struct)时,realloc 才安全
  • 即便如此,也得确保原内存由 malloc 分配(new 分配的不能传给 realloc
  • 现代 C++ 工程中,混用 malloc/new 是严重设计异味

自定义类里模拟动态数组要管好三件事

如果真要封装(比如教学或特殊内存池),核心不是“怎么扩容”,而是“谁负责生命周期”。漏掉任一环节都会崩。

  • 析构函数必须 delete[] data_,否则内存泄漏
  • 拷贝构造函数operator= 必须深拷贝(否则两个对象共用一块内存)
  • 移动构造函数要置空源对象的 data_size_,防止析构时重复释放

容易被忽略的点:扩容时若元素类型有非平凡析构函数(比如含 std::mutex),复制必须调用拷贝构造,不能 memcpy

text=ZqhQzanResources