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.