不能对 new 分配的内存使用 realloc,因其不调用构造/析构函数,会导致未定义行为;应优先使用 std::vector,它自动安全处理扩容、移动语义和异常;仅对 malloc 分配的 pod 类型可安全使用 realloc。

realloc 在 C++ 里不能直接用
你不能在 C++ 中对 new 出来的内存调用 realloc——它只接受 malloc/calloc/realloc 分配的内存块,而 new 返回的是由 C++ 运行时管理的、可能带构造/析构语义的地址。realloc 不会调用构造函数或析构函数,强行传入 new 指针会导致未定义行为,常见表现是程序崩溃或对象状态错乱。
用 std::vector 替代手动 realloc 是最安全的选择
std::vector 内部就是靠类似“分配新内存 → 移动/拷贝元素 → 释放旧内存”的逻辑实现扩容,但它自动处理了构造、析构、异常安全和类型对齐。你不需要也不该自己模拟这套流程。
- 扩容只需调用
push_back()或resize(),vector会在需要时按指数增长(通常是 1.5× 或 2×)重新分配 - 若需预留空间避免多次分配,用
reserve(n);它不改变size(),只影响capacity() - 移动语义下,
std::vector<t></t>在 C++11 及以后对可移动类型(如std::string、自定义移动构造函数的类)会调用移动而非拷贝,性能有保障
非要手写扩容?必须用 malloc + placement new + 析构 + free
如果你在极少数场景(如嵌入式、无 STL 环境、或必须控制内存布局)下坚持不用 vector,那不能用 realloc,而应:
- 用
malloc分配原始内存(不是new char[]),确保类型对齐可用std::align或aligned_alloc(C++17) - 对每个已有对象调用析构函数(
obj.~T()),再用 placement new 在新内存中逐个构造 - 用
free释放旧内存,不能用delete(因为不是new分配的) - 注意异常:若构造中途抛异常,已构造的对象要手动析构,否则泄漏
示例关键片段(简化版,省略异常处理):
T* old_ptr = static_cast<t>(old_mem); T* new_ptr = static_cast<t>(malloc(new_cap * sizeof(T))); for (size_t i = 0; i <h3>realloc 唯一合法场景:纯 POD 类型 + malloc 分配</h3> <p>只有当你用 <code>malloc</code> 分配、且类型是严格 POD(比如 <code>int</code>、<code>float</code>、<code>struct</code> 无构造函数/虚函数/非POD成员)时,<code>realloc</code> 才可安全使用。</p> <ul> <li>例如:<code>int* p = static_cast<int>(malloc(n * sizeof(int))); p = static_cast<int>(realloc(p, m * sizeof(int))); </int></int></code> </li> <li>但此时你已脱离 C++ 对象模型,无法存储 <code>std::string</code>、<code>std::vector</code> 或任何有构造/析构逻辑的类型</li> <li>一旦涉及非 POD,<code>realloc</code> 就是 bug 温床,编译器不会报错,运行时才出问题</li> </ul> <p>真正需要动态数组时,<code>std::vector</code> 不是“替代方案”,而是唯一合理选择;手写扩容不是优化,是给自己埋雷。最容易被忽略的点是:你以为 <code>realloc</code> 快,其实现代 <code>vector</code> 的移动扩容在绝大多数情况下更快,且绝对安全。</p></t></t>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











