Why use std::vector instead of realloc?

Viewed 497

Here, in this question, it's stated that there is no realloc-like operator or function in c++. If you wish to resize an array, just just std::vector instead. I've even seen Stroustrup saying the same thing here.

I believe it's not hard to implement one. There should be a reason for not implementing one. The answers only say to use std::vector but not why it's not implemented.

What is the reason for not implementing realloc-like operator or function and preferring to use std::vector instead?

4 Answers

What is the reason for not implementing realloc-like operator or function and preferring to use std::vector instead?

Save time. Don't chase bugs in your own code for a problem that has long been solved. Idiomatic C++ and readability. Get answers to your questions easily and quickly. Customize the realloc part by an allocator.

I believe it's not hard to implement one

That heavily depends on what you need from the template you intend to write. For a general-purpose std::vector-like one, have a look at the source code (libcxx's 3400 line vector header is here). I bet you will revise you initial assumption on the low complexity of such construct.

There's several advantages.

  • Vector keeps track of its size and capacity, which means you don't have to do this yourself.
  • Because the current size is part of the vector object itself, you can pass a vector (by reference or by value) without needing an additional size parameter. This is especially useful when returning a vector as the caller doesn't need to receive the size through some side-channel.
  • When reallocating, vector will add more capacity than is needed to add just the element(s) requested to be added. This sounds wasteful but saves time as fewer reallocations are needed.
  • Vector manages its own memory; using vector lets you focus on the more interesting parts of your program instead of the details of managing memory, which are relatively uninteresting and tricky to get exactly right.
  • Vector supports many operations that arrays don't natively support, such as removing elements from the middle and making copies of an entire vector.

realloc's expectation that there might be sufficient free space after the current allocation just does not fit well with modern allocators and modern programs.

(There's many more allocation going on, many allocation sizes go to a dedicated pool for that size, and the heap is shared between all the threads in a program.)

In most cases, realloc will have to move content to a completely new allocation, just like vector does. But unlike vector<T>, realloc does not know how to move elements of type T, it only knows how to copy plain data.

Well, as the other answers have explained nicely about the reason for using vectors, I will simply elaborate on why realloc was not implemented. For this, you need to take a look at what realloc actually does. It increases the size of the memory by intelligently using malloc() and free(). You need to understand, that though it seems to simply increase the size, it does not actually increase the size, but instead allocates another block of memory with the required size (That explains the name realloc).

Take a look at the following lines:

int* iarr = (int*)malloc(sizeof(iarr)*5);
iarr = (int*)realloc(6,sizeof(iarr));  //this is completely discouraged
//what you're supposed to do here is:
int* iarr2 = (int*)realloc(iarr,1 + sizeof(iarr));  //copies the old data to new block implicitly
//this not only saves the previous state, but also allows you to check if realloc succeeded

In C++, this can be (if it is must) achieved, by writing:

int* iarr = new int[5];
int* iarr2 = new int[6];
for(int i = 0; i < 5; i++) {
    iarr2[i] = iarr[i];
}
delete[] iarr;

The only use of realloc was to increase the memory capacity; as C arrays did not do that automatically they had to provide a mechanism to do so; which has been implicitly implemented in most of the containers, making the reason for having a realloc in the first place, moot.

Related