命名空间
变体
操作

std::realloc

来自 cppreference.cn
< cpp‎ | memory‎ | c
 
 
内存管理库
(仅为阐释目的*)
未初始化内存算法
(C++17)
(C++17)
(C++17)
约束未初始化
内存算法
C 库
realloc

分配器
内存资源
垃圾回收支持
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
未初始化存储
(直到 C++20*)
(直到 C++20*)
显式生命周期管理
 
定义于头文件 <cstdlib>
void* realloc( void* ptr, std::size_t new_size );

重新分配给定的内存区域(隐式地创建目标区域中的对象)。它必须先前由 std::mallocstd::callocstd::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::freestd::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