std::realloc
来自 cppreference.cn
定义于头文件 <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 文档 关于 realloc
|