[comp.lang.c++] c++ storage management of arrays

act@eng.cam.ac.uk (A.C.Thornton) (02/08/91)

I have a question about the allocation of arrays of classes.  How
do I increase the size of an array of classes after I've already
allocated it using "new."  For example:

If I've defined the class Test in a header file as:

	class Test {
	  public:
	     double v1;
	     // ...

	     test();
	     // ...
	}

then instantiate an array of Test using:

        int bufsize=10;
	Test *test = new Test[bufsize];

How do I increase the size of that array later on in the code when
I need a larger buffer size? (like realloc in C)

Thanks in advance for your help.

				Anna C. Thornton
				Engineering Design Centre
				Cambridge University
				Cambridge CB3 9ET
					UK
	

horstman@mathcs.sjsu.edu (Cay Horstmann) (02/10/91)

In article <21795@rasp.eng.cam.ac.uk> act@eng.cam.ac.uk (A.C.Thornton) writes:
>I have a question about the allocation of arrays of classes.  How
>do I increase the size of an array of classes after I've already
>allocated it using "new."  

Unfortunately, you cannot easily do that except for the obvious solution
of allocating a bigger array and copying over the existing elements. 

Note that you CANNOT use memcpy to copy the existing elements if the array
contains objects with nontrivial copy semantics. 

For syntactic sugar, you could define an overloaded operator new
for this case ( like a = new T[50] , /* ... */ a = new(a) T[100]; )
Note that the new to be changed is the global ::new. 

Cay

jimad@microsoft.UUCP (Jim ADCOCK) (02/16/91)

In article <21795@rasp.eng.cam.ac.uk> act@eng.cam.ac.uk (A.C.Thornton) writes:
|I have a question about the allocation of arrays of classes.  How
|do I increase the size of an array of classes after I've already
|allocated it using "new."  For example:
|
|If I've defined the class Test in a header file as:
|
|	class Test {
|	  public:
|	     double v1;
|	     // ...
|
|	     test();
|	     // ...
|	}
|
|then instantiate an array of Test using:
|
|        int bufsize=10;
|	Test *test = new Test[bufsize];
|
|How do I increase the size of that array later on in the code when
|I need a larger buffer size? (like realloc in C)

Unfortunately, C++ always allocates arrays using the global new operator,
and realloc is not a feature of new/delete, but rather of malloc/free
allocators.  Some C++ implementations may base their new/deletes on 
malloc/free, but as of today, this is not guaranteed.

One option then, is to override the global operator new/delete:

inline void* ::operator new(size_t size) { return malloc(size); }
inline void ::operator delete(void* p) { free(p); }
inline void* resize(void* p, size_t size) { return realloc(p, size); }

[Serious users have to worry about memory allocation failures, of course]

If you don't want to override the global operator new/delete, and only
need to do a few of these allocations/resizes, you might want to use
(a suitably encapsulated) placement version of new hack:

inline void* ::operator new(size_t size, void* where) { return p; }

....

        int bufsize=10;
	Test *test = new(malloc(bufsize*sizeof(Test))) Test[bufsize];
....
	test = (Test*)realloc(test, newsize*sizeof(Test));	


The reason you might want to do this being that some C++ implementations 
may have new/deletes implementations that are much faster than the
historically very-slow implementations of malloc/free.  If so, then
when you globally override new/delete you force all allocations to 
use the slower malloc/free allocations.  If you're willing to use
the placement hack, then you only have to use the slow malloc/free
implementations for your arrays, and can use the faster built-in
new/delete allocations for fixed-size objects.

Of course, yet another choice is to override global new/delete to use 
malloc/free for all your arrays, and then re-override new/delete in your
classes to use some fast, fixed size allocation scheme, 
[fixed size pools, for example] for your individual object allocations.