alternate of realloc in C++

Started by
9 comments, last by jpetrie 17 years, 12 months ago
Like we have realloc in C what can we do to reallcate the memory in C++. I don't think there is any keyword.
Advertisement
Hey bud,

The best we can do is to allocate bigger and copy across.

Hope that helps,

Dave
The realloc func was a horrible function in C. There is no equivalent in C++.
-------Harmotion - Free 1v1 top-down shooter!Double Jump StudiosBlog
That's really bad.
It's not really bad.

I prefer to have explicit control over the allocation and deallocation of memory in my code. I intentionally never used realloc() in C.

Also it is often the case that at any time you need to resize some memory in C++, you could use one of the containers in either STL or Boost.

Why do you think it is really bad? :)

Dave
Quote:Original post by blaze02
The realloc func was a horrible function in C. There is no equivalent in C++.


Why is realloc bad? I think it's quite useful if you want to for example implement a vector class in C. I know C++ comes with std::vector but why not use realloc in C?

Bojan
Galactic Marbles: www.scientiagames.com
Quote:Original post by TEUTON
Like we have realloc in C what can we do to reallcate the memory in C++.

I don't think there is any keyword.


Nope. Instead, use std::vector.

int * foo = malloc( sizeof(int) * 30 );foo = realloc( foo , sizeof(int) * 40 );assert( foo );//will crash/screwup on allocation failure (I was too lazy to add error handlingfree( foo ); //if we return an error, we'll need to free() there too, remember!


Becomes:

std::vector< int > foo( 30 );foo.resize( 40 );//will throw std::bad_alloc on allocation failure//cleans up after itself using a destructor
If I remember rightly, if vector ever needs to change the size of the memory allocated to it (either up or down), it _always_ copies the lot, wheras realloc would sometimes be able to change the size of the block but keep the address the same, thus not requiring moving data. This would probably happen whenever the new size passed to realloc was smaller than the previous size (depends on implementation)

vector makes this slightly nicer by overallocating space for itself so that if it gets slightly larger it doesn't need to change the size of the memory chunk. I also think you can tune the overallocation on a per vector-type basis, but I haven't tried yet.


Dave:
However, I don't see how realloc is not explicit control - is it because it decides whether or not to change the pointer.


I personally think allocation in C++ is way more obfuscated, restrictive and inconsistent than in C. However, it is faster (although it may just be that's only because they decided not to let you do the slow stuff - like resizeable chunks).


You can of course do this:
void* myRealloc(void* ptr, size_t new, size_t old) { // <--- NOTE THE "old" size.    void* new_ptr = ::operator new(size_t);    memcpy(new_ptr, old_ptr, (old > new) ? new : old);    ::operator delete(ptr);    return new_ptr;}// Not sure if that's the right syntax, but I hope you get the idea.

You almost always know how big the allocation is when you want to resize, so requiring the "old" value shouldn't be too much of a hassle.

Of course, this is not as fast as realloc(), since it always moves the data.

Doesn't malloc actually allocate more space then desired so that if you need to change the space with realloc it probably won't have to move the data?
Quote:Original post by darkchrono4
Doesn't malloc actually allocate more space then desired so that if you need to change the space with realloc it probably won't have to move the data?


That's a possibility. Of course, if you don't use realloc(), that could mean a lot of space allocated for no good reason that will go to waste, unless you keep the extra relatively small, in which case you probably will have to move the data sometime.

It's equivilant, std::vector, usually only gives you extra data if you end up growing it past it's initial size:

resize( n ) {    if ( n > capacity() ) grow_memory_to( std::max( n , 2 * capacity() ) );    ...}


By choosing whichever is larger of N and 2*capacity() (or 1.5* on some implementations), this allows inserting elements at the end to become amortized constant time, meaning performance won't sink into the drain with large data sets push_back()ing elements if you didn't reserve() enough memory (you guessed incorrectly), and if you did reserve() the right amount of memory (you were right) you won't be wasting memory.

Quote:I personally think allocation in C++ is way more obfuscated, restrictive and inconsistent than in C. However, it is faster (although it may just be that's only because they decided not to let you do the slow stuff - like resizeable chunks).


Not sure why you'd say obfuscated.

While new/delete might be fairly restricted, when you look at the STL containers (part of the standard C++ library), each one takes a plug-and-play allocator, meaning each container isn't hardwired to a single allocation method. I'd say that's less restrictive.

Not sure what you're refering to when you say inconsistent (although there are quite a few inconsistencies in C++ in general). And none of this "they decided not to let you do the slow stuff" junk:

For objects, std::vector offers the C realloc equivilant with appropriate object (de)constructing.
You can still use realloc with malloc/free for raw memory (#include <cstdlib>)

This topic is closed to new replies.

Advertisement