如何在 C++ 中“重新分配”?

问题描述 投票:0回答:4

如何在 C++ 中

realloc
?语言中似乎缺少它 - 有
new
delete
但没有
resize

我需要它,因为当我的程序读取更多数据时,我需要重新分配缓冲区来保存它。我不认为

delete
旧指针和
new
一个新的、更大的指针是正确的选择。

c++ new-operator realloc delete-operator
4个回答
64
投票

使用

::std::vector

Type* t = (Type*)malloc(sizeof(Type)*n) 
memset(t, 0, sizeof(Type)*m)

成为

::std::vector<Type> t(n, 0);

然后

t = (Type*)realloc(t, sizeof(Type) * n2);

成为

t.resize(n2);

如果你想将指针传递给函数,而不是

Foo(t)

使用

Foo(&t[0])

这是绝对正确的 C++ 代码,因为向量是一个智能 C 数组。


54
投票

正确的选择可能是使用一个可以为您完成工作的容器,例如

std::vector

new
delete
无法调整大小,因为它们分配的内存刚好足以容纳给定类型的对象。给定类型的大小永远不会改变。有
new[]
delete[]
,但几乎没有理由使用它们。

无论如何,

realloc
在C中所做的很可能只是
malloc
memcpy
free
,尽管如果有足够的连续空闲内存可用,内存管理器可以做一些聪明的事情。


44
投票

在 C++ 中调整大小很尴尬,因为可能需要调用构造函数和析构函数。

我不认为在 C++ 中你不能有一个

resize[]
运算符与
new[]
delete[]
一起使用,这没有什么根本原因,它的作用与此类似:

newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;

显然,

oldsize
将从秘密位置检索,与在
delete[]
中一样,并且
Type
将来自操作数的类型。如果 Type 不可复制,
resize[]
将会失败 - 这是正确的,因为此类对象根本无法重新定位。最后,上面的代码在分配对象之前默认构造对象,这是您不希望的实际行为。

有一个可能的优化,即为新缩小的数组“超出末尾”的对象调用析构函数,而不执行其他操作。标准必须定义是否需要这种优化(就像当您

newsize <= oldsize
向量时)、允许但未指定、允许但取决于实现还是禁止。

然后你应该问自己的问题是,“提供这个实际上有用吗,因为

resize()

也做到了这一点,并且是专门设计来提供可调整大小的容器(连续内存 - 在 C 中省略了这一要求) ++98 但已在 C++03 中修复)这比采用 C++ 处理方式的数组更合适?”


我认为答案被广泛认为是“不”。如果您想以 C 方式执行可调整大小的缓冲区,请使用

vector

,它在 C++ 中可用。如果您想以 C++ 方式调整大小的缓冲区,请使用向量(或

malloc / free / realloc
,如果您实际上不需要连续存储)。不要尝试通过使用
deque
作为原始缓冲区来混合两者,除非您正在实现类似矢量的容器。
    


0
投票

编译为:

new[]

代码:

g++ -std=c++2a -O2 -Wall -pedantic foo.cpp

	
© www.soinside.com 2019 - 2024. All rights reserved.