如何在C++中使用realloc
?它似乎在语言中缺失了--有new
和delete
,但没有resize
!
我需要它,因为当我的程序读取更多的数据时,我需要重新分配缓冲区来容纳它。我不认为在旧指针上delete
而在一个新的、更大的指针上new
是正确的选择。
发布于 2010-08-14 19:11:57
使用::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数组。
发布于 2010-08-14 18:42:06
正确的选择可能是使用为您完成此工作的容器,如std::vector
。
new
和delete
无法调整大小,因为它们分配的内存恰好足以容纳给定类型的对象。给定类型的大小永远不会改变。有new[]
和delete[]
,但几乎没有理由使用它们。
不管怎样,realloc
在C中所做的可能只是一个malloc
,memcpy
和free
,尽管如果有足够的连续空闲内存可用,内存管理器可以做一些聪明的事情。
发布于 2010-08-14 20:36:59
在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
将来自操作数的类型。在类型不可复制的情况下,resize[]
将失败-这是正确的,因为这样的对象根本不能被重新定位。最后,上面的代码在赋值对象之前默认构造对象,这并不是您想要的实际行为。
有一个可能的优化,在newsize <= oldsize
中,调用对象的析构函数“超过”新安装的数组的末尾,而不做任何其他事情。标准必须定义这种优化是必需的(就像你使用resize()
时一样),允许但未指定,允许但依赖于实现,还是禁止。
然后,您应该问自己的问题是:“鉴于vector
也这样做,并且专门设计用于提供一个可调整大小的容器(连续内存--该要求在C++98中省略,但在C++03中得到了解决),提供此功能是否真的有用?它比具有C++方式的数组更适合?”
我认为答案被广泛认为是“不”。如果你想用C语言做可调整大小的缓冲区,可以使用C++中提供的malloc / free / realloc
。如果你想用C++的方式做可调整大小的缓冲区,使用一个向量(或者deque
,如果你实际上不需要连续的存储)。不要试图通过将new[]
用于原始缓冲区来混合这两者,除非您正在实现一个类似向量的容器。
https://stackoverflow.com/questions/3482941
复制相似问题