How do you 'realloc' in C++?
How can I realloc
in C++? It seems to be missing from the language - there is new
and delete
but not resize
!
I need it because as my program reads more data, I need to reallocate the buffer to hold it. I don't think delete
ing the old pointer and new
ing a new, bigger one, is the right option.
Use ::std::vector!
Type* t = (Type*)malloc(sizeof(Type)*n)
memset(t, 0, sizeof(Type)*m)
becomes
::std::vector<Type> t(n, 0);
Then
t = (Type*)realloc(t, sizeof(Type) * n2);
becomes
t.resize(n2);
If you want to pass pointer into function, instead of
Foo(t)
use
Foo(&t[0])
It is absolutely correct C++ code, because vector is a smart C-array.
The right option is probably to use a container that does the work for you, like std::vector
.
new
and delete
cannot resize, because they allocate just enough memory to hold an object of the given type. The size of a given type will never change. There are new[]
and delete[]
but there's hardly ever a reason to use them.
What realloc
does in C is likely to be just a malloc
, memcpy
and free
, anyway, although memory managers are allowed to do something clever if there is enough contiguous free memory available.
Resizing in C++ is awkward because of the potential need to call constructors and destructors.
I don't think there's a fundamental reason why in C++ you couldn't have a resize[]
operator to go with new[]
and delete[]
, that did something similar to this:
newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;
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.