views:

954

answers:

5

In C++, I believe, a better way of dealing with reallocation is to use a STL vectors, as it guarantees the contiguous storage locations.

I have couple question to understand the difference:

  1. Is there any scenario in which I need to prefer realloc over vector ?
  2. Is there anything else ( apart from vector ) which is equivalent to realloc in C++?

Thanks,

+6  A: 

Contiguous memory is also guaranteed by realloc so that's not a reason not to use it.

However, I would prefer to use a vector in C++ since it's at a higher level of abstraction, hence it makes the code easier to write.

The only possible reason I can think for using realloc (over vector) for an array-type scenario, is raw speed. It may be (and I stress the word "may" - measure, don't guess) faster.

However, you have to handle your own reallocations, which is more work. I'd rather have code that runs a little slower, if I can deliver it and get paid quicker.

I can't answer your second question since my knowledge of STL is not huge. Every single neuron I have is currently dedicated to storing that 14% of the Java classes that I know about and use regularly :-)

paxdiablo
+7  A: 

It is only vector, which is guaranteed to have contiguous memory. Not the others.

realloc is a C memory management function. It's use is not encouraged in C++ code. Here's Stroustrup telling you why: Why doesn't C++ have an equivalent to realloc()?

However, realloc() is only guaranteed to work on arrays allocated by malloc() (and similar functions) containing objects without user-defined copy constructors. Also, please remember that contrary to naive expectations, realloc() occasionally does copy its argument array.

dirkgently
realloc won't work with anything but POD types, as it does not know about constructors/destructors.
lothar
vector's also have the advantage over malloc's memory in that they will be deleted when they go out of scope, thus decreasing memory leaks when exceptions are thrown, when you forget to free() the memory, etc.
Jason Harrison
A: 

I guess it's only a vector.

I haven't seen anyone who would suggest using realloc in C++.

Shree
+9  A: 

The set of C functions (malloc, calloc, realloc, free) are raw memory operations. They will create/modify/release a given buffer in memory, but the memory will have no type and no constructors will be called.

C++ does not have an equivalent of realloc, but only typesafe equivalents to malloc/free through the use of new/new[] and delete/delete[]. The C++ versions will both acquire the memory from the system and initialize it by calling the appropriate constructors. Using delete will call the destructors of the objects and then release the memory. C and C++ versions are not compatible, if you acquire memory with malloc (even if you call the inplace constructor on the received memory) you cannot release it with delete/delete[] as it is undefined behavior.

Using realloc in C++ might be unsafe, as it will bitwise copy the objects from one memory area to the next. Sometimes your objects will not deal properly with memory moves (say that your object has both an attribute and a reference to it, after bitwise moving it the reference will be pointing to the old position rather than the real attribute). Inside vector, whenever the memory needs to grow, a new memory are is acquired with new[] and then all objects are copy (or copy constructed) in the new positions using the appropriate C++ operations before deleting the old elements.

Whenever vector grows in size (reserved size, not used size) it will create a complete new memory area and move all the objects. On the other hand, realloc will only move the memory block to another position if there is not enough contiguous space after the pointer to just grow it. Vectors do not decrease size. Never. When you clear the elements, the reserved memory is still held.

Finally, there is a higher level of abstraction in vector than in realloc even for POD types (that are safe to be moved with C-like constructs). The equivalent to vector would be a structure that holds the pointer to the memory buffer, a used elements count and a reserved (buffer size) and the set of functions that deal with acquiring more memory as needed and updating the indexes with each operation.

David Rodríguez - dribeas
+3  A: 

One of the main benefits of std::vector is that when it reallocates itself internally from naturally growing, it chooses a size that is 2x larger than the current size (usually - but always a constant multiplier). This means that push_back's have amortized O(1) cost.

Realloc will give you finer control over how you allocate memory, but with great power comes great responsibility. If you all you are doing is the equivalent of push_back, and you realloc each time you add an element, that is potentially an O(N) operation on each addition to the array.

Greg Rogers