你如何在C++中'realloc'?

bod*_*ydo 78 c++ realloc new-operator delete-operator

我怎么能用reallocC++?它似乎在语言中缺失 - 有new,delete但不是resize!

我需要它,因为当我的程序读取更多数据时,我需要重新分配缓冲区来保存它.我不认为delete旧指针和new新的更大的指针是正确的选择.

f0b*_*b0s 47

使用:: std :: vector!

Type* t = (Type*)malloc(sizeof(Type)*n) 
memset(t, 0, sizeof(Type)*m)
Run Code Online (Sandbox Code Playgroud)

::std::vector<Type> t(n, 0);
Run Code Online (Sandbox Code Playgroud)

然后

t = (Type*)realloc(t, sizeof(Type) * n2);
Run Code Online (Sandbox Code Playgroud)

t.resize(n2);
Run Code Online (Sandbox Code Playgroud)

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

Foo(t)
Run Code Online (Sandbox Code Playgroud)

使用

Foo(&t[0])
Run Code Online (Sandbox Code Playgroud)

这是绝对正确的C++代码,因为vector是一个智能C-array.

  • memset 行不应该是 memset(t, 0, sizeof(T) * n); 吗?n 而不是 m? (2认同)
  • 在 C++11 中,现在可以使用 `t.data()` 而不是 `&amp;t[0]` (2认同)

Tho*_*mas 45

正确的选择可能是使用一个能为你工作的容器,比如std::vector.

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

什么realloc做用C很可能只是一个malloc,memcpy并且free,无论如何,虽然内存管理器被允许这样做的很漂亮,如果有足够的可用连续可用内存.

  • @bodacydo:不要实现增长缓冲区,只需使用`std :: vector` - 它会在需要时自动增长,你可以预先分配内存(`reserve()`). (6认同)
  • @bod:是的,它可以.(顺便说一句,`std :: string`也可以.) (4认同)
  • 使用std :: vector <T>.这就是它的用途.在C++中,没有任何理由自己使用new/delete/new []/delete [],除非您明确地编写资源管理类. (3认同)
  • 那么在 C++ 中实现不断增长的缓冲区的正确方法是什么?目前我有`char *buf = (char *)malloc(size)`,然后当它变得太小时我做`buf = realloc(size + more_size); 大小 += more_size`。我怎样才能用矢量做到这一点? (2认同)
  • 听起来像`thevector.resize(previous_size + incoming_size)`,后跟``memcpy`(或类似)到`&thevector [previous_size]`,就是你需要的.矢量的数据保证"像数组一样"存储. (2认同)

Ste*_*sop 33

在C++中调整大小是不方便的,因为可能需要调用构造函数和析构函数.

我不认为有一个根本原因在C++中,你可以没有一个resize[]运营商去与new[]delete[],即没有类似的东西,以这样的:

newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;
Run Code Online (Sandbox Code Playgroud)

Obviously oldsize would be retrieved from a secret location, same is it is in delete[], and Type would come from the type of the operand. resize[] would fail where the Type is not copyable - which is correct, since such objects simply cannot be relocated. Finally, the above code default-constructs the objects before assigning them, which you would not want as the actual behaviour.

There's a possible optimisation where newsize <= oldsize, to call destructors for the objects "past the end" of the newly-ensmallened array and do nothing else. The standard would have to define whether this optimisation is required (as when you resize() a vector), permitted but unspecified, permitted but implementation-dependent, or forbidden.

The question you should then ask yourself is, "is it actually useful to provide this, given that vector also does it, and is designed specifically to provide a resize-able container (of contiguous memory--that requirement omitted in C++98 but fixed in C++03) that's a better fit than arrays with the C++ ways of doing things?"

I think the answer is widely thought to be "no". If you want to do resizeable buffers the C way, use malloc / free / realloc, which are available in C++. If you want to do resizeable buffers the C++ way, use a vector (or deque, if you don't actually need contiguous storage). Don't try to mix the two by using new[] for raw buffers, unless you're implementing a vector-like container.