std::realloc
来自 cppreference.com
定义在头文件 <cstdlib> 中 |
||
void* realloc( void* ptr, std::size_t new_size ); |
||
重新分配给定的内存区域 (隐式创建 目标区域中的对象)。它必须事先由 std::malloc、std::calloc 或 std::realloc
分配,并且还没有使用 std::free 释放,否则结果未定义。
重新分配通过以下两种方式之一完成:
a) 如果可能,扩展或收缩 ptr 指向的现有区域。区域的内容在新的和旧的大小中较小的那部分保持不变。如果区域扩展,则数组新部分的内容未定义。
b) 分配一个大小为 new_size 字节的新内存块,将大小等于新的和旧的大小中较小的那部分的内存区域复制到新内存块中,然后释放旧块。
如果内存不足,则不释放旧内存块并返回空指针。
如果 ptr 是空指针,则行为与调用 std::malloc(new_size) 相同。
如果 new_size 为零,则行为由实现定义:可能返回空指针(在这种情况下,旧内存块可能被释放,也可能不被释放),或者可能返回一些非空指针,该指针可能无法用于访问存储。 此类用法已弃用(通过 C DR 400)。(自 C++20 起)
以下函数要求线程安全
分配或释放特定存储单元的这些函数的调用按单个总顺序发生,并且每个此类释放调用都 发生在 此顺序中的下一个分配(如果有)之前。 |
(自 C++11 起) |
内容 |
[编辑] 参数
ptr | - | 指向要重新分配的内存区域的指针 |
new_size | - | 数组的新大小 |
[编辑] 返回值
成功时,返回指向新分配的内存开头的指针。为了避免内存泄漏,返回的指针必须使用 std::free 或 std::realloc
释放。原始指针 ptr 已失效,任何对它的访问都是 未定义的行为(即使重新分配是在原地进行的)。
失败时,返回空指针。原始指针 ptr 仍然有效,可能需要使用 std::free 释放。
[编辑] 说明
由于重新分配可能涉及逐字节复制(无论它是否扩展或收缩区域),因此这些对象必须是 TriviallyCopyable 类型的必要条件(但不足)。
一些非标准库定义了一个类型特征“BitwiseMovable”或“Relocatable”,用于描述一种没有
- 外部引用(例如列表或树的节点,它们持有对另一个元素的引用),以及
- 内部引用(例如成员指针,它可能持有另一个成员的地址)。
即使对象的复制构造函数不是平凡的,在重新分配存储空间后也可以访问此类类型的对象。
[编辑] 示例
运行此代码
#include <cassert> #include <cstdlib> #include <new> class MallocDynamicBuffer { char* p; public: explicit MallocDynamicBuffer(std::size_t initial = 0) : p(nullptr) { resize(initial); } ~MallocDynamicBuffer() { std::free(p); } void resize(std::size_t newSize) { if (newSize == 0) // this check is not strictly needed, { std::free(p); // but zero-size realloc is deprecated in C p = nullptr; } else { if (void* mem = std::realloc(p, newSize)) p = static_cast<char*>(mem); else throw std::bad_alloc(); } } char& operator[](size_t n) { return p[n]; } char operator[](size_t n) const { return p[n]; } }; int main() { MallocDynamicBuffer buf1(1024); buf1[5] = 'f'; buf1.resize(10); // shrink assert(buf1[5] == 'f'); buf1.resize(1024); // grow assert(buf1[5] == 'f'); }
[编辑] 另请参阅
C 文档 for realloc
|