Ouch! Exception During Realloc of Dynamic Array of Smart Pointers

Started by
20 comments, last by Raeldor 18 years, 7 months ago
Quote:Original post by Raeldor
Quote:Original post by c2_0
Make a templated, type safe, dynamic array, and use new and delete for resizing it.

Or, use one of the standard library dynamic containers; std::vector if you want continious memory.


Cool. I changed my mallocs and frees to 'new' and 'delete []'. It seems to work great now. For the array resize, I had to use...
*** Source Snippet Removed ***
which seems to work, but may not be the most efficient?

Thanks!


To be efficient you'd need to use something like std::uninitialized_copy() and manipulate raw memory. This is not something that's worth time worrying about when std::vector does it for you.
Advertisement
Quote:Original post by SiCrane
To be efficient you'd need to use something like std::uninitialized_copy() and manipulate raw memory. This is not something that's worth time worrying about when std::vector does it for you.


Quoted for emphasis.
I've just edited the class and added a resize member.. the reason why I took out the resize member was that I didn't really need it. I use a vector for dynamic arrays with varying size, and this class for dynamic arrays that stay the same once sized.
my-eulogy - A blog about coding and gfxsdgi - Semi-Daily Game IdeaChunkyHacker - Viewer for Relic chunky formats (used in DOW)
Quote:Original post by e-u-l-o-g-y:
void Resize(int size){	int copySize = min(size, m_size);	T* pDest = new T[size];	T* pSrc = m_pBuffer;	m_pBuffer = pDest;	m_size = size;	while (copySize--)		*(pDest++) = *(pSrc++);}

Nice memory leak and corrupts the container if a copy constructor throws (some objects will be lost). Just use std::vector (or another suitable container).

Enigma
Seriously, why aren't you using std::vector?

It is:

easier
faster (really, these guys write containers for a living, you don't)
easier to get help on, that is if you need help
feature complete (or at least much closer than whatever you are making)

the downside: you'll have to swallow your pride and maybe get used to some of the function names being different from what you would have named them.
Quote:Original post by Glak
Seriously, why aren't you using std::vector?

It is:

easier
faster (really, these guys write containers for a living, you don't)
easier to get help on, that is if you need help
feature complete (or at least much closer than whatever you are making)

the downside: you'll have to swallow your pride and maybe get used to some of the function names being different from what you would have named them.


Learning exercise? Plus I'm a control freak! :P
Quote:Original post by Raeldor
Learning exercise?

That's valid. Once you've learned how to implement a dynamic array, though, throw it out and use std::vector.
Quote:Plus I'm a control freak! :P

If you're a control freak, you'll enjoy the fact that std::vector is guaranteed bug-free, gives you a huge amount of customizability by exposing its allocation interface, and works well with the rest of the standard library. If, on the other hand, you are a masochist, you should use a custom-written dynamic array class, because it'll force you to worry about whether it's buggy every time you run into an unknown bug that is at all related to its use. Yow!
Yeah... nice memory leak :P ... Just coded it up, but I'm a bit too tired to be coding now. Have been using garbage collection for too long :P. As I said.. I dropped it for std::vector.
my-eulogy - A blog about coding and gfxsdgi - Semi-Daily Game IdeaChunkyHacker - Viewer for Relic chunky formats (used in DOW)
if you are creating an array of auto_ptr.

For auto_ptr, copies are NOT equivalent.

It turns out that this has important effects when you try to use auto_ptrs with generic code that does make copies and isn't necessarily aware that copies aren't equivalent (after all, usually copies are!). Consider the following code that I regularly see posted on the C++ newsgroups:

// Example 8: Danger, Will Robinson!
//
vector > v;

/* ... */

sort( v.begin(), v.end() );

It is never safe to put auto_ptrs into standard containers. Some people will tell you that their compiler and library compiles this fine, and others will tell you that they've seen exactly this example recommended in the documentation of a certain popular compiler; don't listen to them.

The problem is that auto_ptr does not quite meet the requirements of a type you can put into containers, because copies of auto_ptrs are not equivalent. For one thing, there's nothing that says a vector can't just decide to up and make an "extra" internal copy of some object it contains. For another, when you call generic functions that will copy elements, like sort() does, the functions have to be able to assume that copies are going to be equivalent. At least one popular sort internally takes a copy of a "pivot" element, and if you try to make it work on auto_ptrs it will merrily take a copy of the pivot auto_ptr object (thereby taking ownership and putting it in a temporary auto_ptr on the side), do the rest of its work on the sequence (including taking further copies of the now-non-owning auto_ptr that was picked as a pivot value), and when the sort is over the pivot is destroyed and you have a problem: At least one auto_ptr in the sequence (the one that was the pivot value) no longer owns the pointer it once held, and in fact the pointer it held has already been deleted!

So the standards committee bent over backwards to do everything it could to help you out: The Standard auto_ptr was deliberately and specifically designed to break if you try to use it with the standard containers (or, at least, to break with most natural implementations of the standard library). To do this, the committee used a trick: auto_ptr's copy constructor and copy assignment operator take references to non-const to the right-hand-side object. The standard containers' single-element insert() functions take a reference to const, and hence won't work with auto_ptrs.

here is the full article:
http://www.gotw.ca/publications/using_auto_ptr_effectively.htm
// Example 8: Danger, Will Robinson!
//
vector > v;

/* ... */

sort( v.begin(), v.end() );

This topic is closed to new replies.

Advertisement