Realloc for C++
Ok, I know you''re not supposed to free() memory allocated
with new, or delete memory allocated with malloc.
My question is, what is the accepted way to realloc memory
using C++? I mean, assume you have a class called SphereClass. What if you wanted an array of SphereClass''s
that can grow? Do you have to make a new array, copy,
(making sure you made a copy constructor for SphereClass of
course), and then delete the old one? This sounds kind of
inefficient to me...
-ns-
-ns-
you can try a linked list of SphereClass''s
Carl "trixter"[email=carl@trixoft.com]carl@trixoft.com[/email]http://www.trixoft.com
I made a dynamic array once; the only thing I learned that might be useful to you is that you can eliminate using the copy constructor when you copy from the old array to the new array. Cast the array to a BYTE* beforehand, then use memcpy. To avoid using the destructors of the old array, cast the array to a BYTE* and delete it.
If you're wondering, that's how MFC's dynamic array class does it.
I think the most efficient way to store a variable amount of data (particularly classes) is to use linked lists though.
Good Luck!
- null_pointer
Edited by - null_pointer on 2/23/00 3:55:19 PM
If you're wondering, that's how MFC's dynamic array class does it.
I think the most efficient way to store a variable amount of data (particularly classes) is to use linked lists though.
Good Luck!
- null_pointer
Edited by - null_pointer on 2/23/00 3:55:19 PM
quote: use vectors, doh
FYI, vectors recopy themselves when they need to grow, so you have the same problem.
Now, if you made a vector<SphereClass*> instead of a vector<SphereClass>, then ever object would be allocated separately, no need to copy anything anywhere. However, all these objects would be sprinkled all over memory.
I heard many horror stories about realloc, like it could cause an infinite loop if no contiguous chunk of that size could be found in memory, and that it hid a really inefficient algorhythm. All rumor and hearsay, though.
Edited by - Stoffel on 2/23/00 4:37:32 PM
I would highly recommend against using memcpy on classes.
This is a shallow copy and may not have the desired results.
In the case of when you are resizing an array most of the time that will be OK, however, if you have any self-referencing member pointers then you will get bad results
e.g.
class PointsToSelf
{
private:
long iVal;
long iOtherVal;
long iAnotherVal;
long *iCurTargetVal;
};
and then you set
iCurTargetVal = &iOtherVal
The problem is that when you memcpy the data to the new location the iCurTargetVal will be pointing to the same pointer value that it was before, which is likely to be off in the middle of nowhere.
Now, granted this example is a bit contrived and most folks don't use self-referencing pointers.
Personally, I would go with std::vector.
It has performance characteristics ( I think ) that are similar to an array ( constant time to access an element regardless of array size ) and has the ability to grow.
Although this process is known to be slow. ( But you can seed it with an initial size so that it doesn't have to allocate more memory until it goes past that boundary )
Edited by - SteveC on 2/23/00 5:05:19 PM
This is a shallow copy and may not have the desired results.
In the case of when you are resizing an array most of the time that will be OK, however, if you have any self-referencing member pointers then you will get bad results
e.g.
class PointsToSelf
{
private:
long iVal;
long iOtherVal;
long iAnotherVal;
long *iCurTargetVal;
};
and then you set
iCurTargetVal = &iOtherVal
The problem is that when you memcpy the data to the new location the iCurTargetVal will be pointing to the same pointer value that it was before, which is likely to be off in the middle of nowhere.
Now, granted this example is a bit contrived and most folks don't use self-referencing pointers.
Personally, I would go with std::vector.
It has performance characteristics ( I think ) that are similar to an array ( constant time to access an element regardless of array size ) and has the ability to grow.
Although this process is known to be slow. ( But you can seed it with an initial size so that it doesn't have to allocate more memory until it goes past that boundary )
Edited by - SteveC on 2/23/00 5:05:19 PM
Wow, 3 fast replies.
Staffan, lets assume I MUST use an array, for reasons only I know :-) GOD came down and said to me Tim, You use arrays or you go to Hell.
trixter, yeah that''s usually what I use (linked lists) but this time, like I said, I''m trying to avoid Hell here.
null_pointer (my old friend, we meet again! *grin*) good point, I guess you probably dont need a copy constructor when you''re going to delete the old data (so you dont end up with string aliases and stuff).
I just find it hard to believe that there''s no realloc component for C++ except for realloc itself. Making new memory and copying leaves out one very nice feature of realloc, that it can extend your memory (without physically moving it at all), so making new and copying is usually going to be less efficient. Weird!
Anyways, thanks a ton for the replies everyone
-ns-
Staffan, lets assume I MUST use an array, for reasons only I know :-) GOD came down and said to me Tim, You use arrays or you go to Hell.
trixter, yeah that''s usually what I use (linked lists) but this time, like I said, I''m trying to avoid Hell here.
null_pointer (my old friend, we meet again! *grin*) good point, I guess you probably dont need a copy constructor when you''re going to delete the old data (so you dont end up with string aliases and stuff).
I just find it hard to believe that there''s no realloc component for C++ except for realloc itself. Making new memory and copying leaves out one very nice feature of realloc, that it can extend your memory (without physically moving it at all), so making new and copying is usually going to be less efficient. Weird!
Anyways, thanks a ton for the replies everyone
-ns-
-ns-
The performance hit isn''t really that big. (And just how often is realloc() able to extend your memory without copying? That seems pretty unlikely... I didn''t think it had that functionality at all.)
Anyways, so long as you''re smart about reallocation, and double the allocated space every time you run out, you really shouldn''t notice the performance hit over time (when adding many elements.) Adding an element is still amortized constant time.
As for casting to (char *) and using memcpy() ... that''s just a BadIdea(tm). Aside from self referential pointers, what if elements in your list/array have pointers to each other? Recipe for disaster.
-Brian
Anyways, so long as you''re smart about reallocation, and double the allocated space every time you run out, you really shouldn''t notice the performance hit over time (when adding many elements.) Adding an element is still amortized constant time.
As for casting to (char *) and using memcpy() ... that''s just a BadIdea(tm). Aside from self referential pointers, what if elements in your list/array have pointers to each other? Recipe for disaster.
-Brian
Haha BadIdea (TM)
Good question about realloc actually extending the
memory. Someday I should make a test program that
allocates random sizes of memory and see how many
times the pointer actually changes. I bet in older
environments like DOS it stayed the same more often
than it probably does now.
Thanks for the replies and advice!
-ns-
Good question about realloc actually extending the
memory. Someday I should make a test program that
allocates random sizes of memory and see how many
times the pointer actually changes. I bet in older
environments like DOS it stayed the same more often
than it probably does now.
Thanks for the replies and advice!
-ns-
-ns-
well i'm a big fan of linked lists for dynamic arrays. they always do what i need and and quite fast.
i have my own little library written using void pointers so i can use any data i wish.
i know mfc has a linked list class called CList er something like that. it's also pretty nice but i don't use mfc that much since i mostly write (almost never finish) games.
course you'll have to rewrite a bunch of code to use them.
Edited by - shmaLbus on 2/23/00 6:50:59 PM
i have my own little library written using void pointers so i can use any data i wish.
i know mfc has a linked list class called CList er something like that. it's also pretty nice but i don't use mfc that much since i mostly write (almost never finish) games.
course you'll have to rewrite a bunch of code to use them.
Edited by - shmaLbus on 2/23/00 6:50:59 PM
-werdup-
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement