realloc copies also, just at the bit-level, meaning that realloc cannot be used if the array contains classes
or structs that have virtual methods, constructors, (non-virtual) destructors, or any data members that
are not PODs or simple aggregates themselves.
That's no excuse for not having renew. Why not implement it like this (roughly, assuming new calls malloc in its guts):
1 2 3 4 5 6 7 8 9 10
template <class T> operator renew(T*p, int size){
int old= implementation_getsize(p);//in order for delete[] to work, new[] must store the size somewhere.
if(old>size){
invoke_destructors(p+size,size-old);//destruct the old objects
realloc(p,size);
}elseif(old<size){
invoke_constructors(p+old,old-size);//make new objects
realloc(p,size);
}
}
Just because realloc doesn;t invoke constructors, destructors etc isn't an excuse not to have renew. It's a stupid omission.
When making a dynamic array, new[] forces you to copy the array every time you resize it. That's crazy.
You probably shouldn't be resizing arrays all the time. If you need something that needs to be dynamically sized, you probably should be using a vector.
When you think about it.. managing your own buffer really is just reinventing the wheel. std::vector already does it, so why bother recreating your own mini-version of vector?
Performance is the only reason that comes to mind -- but is there even any substantial performance difference between the two?
Just because realloc doesn;t invoke constructors, destructors etc isn't an excuse not to have renew. It's a stupid omission.
I can't say I completely disagree. Omission of renew does seem odd.
On the other hand, I don't see what good renew would really do. I hardly ever (read: very very rarely) use new[] at all simply because it's easier and safer to use vector.
Well, what exactly does std::vector<int> have down its guts? I hope it's resizing in place when possible! I mean, shouldn't it be implementable using standard c++?
AFAIK vector overshoots allocation when it resizes to anticipate future growth, so if you increase by only a few elements it won't need to reallocate.
You can check this in implementaiton by comparing capacity() vs. size(). size() is how much you're using, and capacity() is how much is actually allocated (ie, when you exceed capacity it will need to reallocate).
By default this does not happen. That's why vector iterators are invalidated whenever the current capacity is exceeded. You can do that with special allocators, but most folks don't mess around with custom allocators when using the STL.
Edit: I may be wrong about this: C++ vectors do not support in-place reallocation of memory, by design; i.e., upon reallocation of a vector, the memory it held will always be copied to a new block of memory using its elements' copy constructor, and then released. This is inefficient for cases where the vector holds plain old data and additional contiguous space beyond the held block of memory is available for allocation. http://en.wikipedia.org/wiki/Vector_%28C%2B%2B%29
std::vector<> on gcc doubles its size when it reallocates. It cannot resize itself without copying because it
needs to allocate the new memory block (using array new) before it frees the old one. Obviously the new
pointer will not overlap the already-allocated block, and it is very unlikely that the newly allocated block
would occur immediately after the already-allocated block.