Question

I am looking for a way to put large arrays of data (stored inside a class holding basic functionality like checks on the data, size etc) into any STL container, like a vector or a queue (FIFO queue is best since I have a producer and a consumer).

The problem is that I have to implement the copy constructor and.. well.. I don't want to make a deep copy (since it takes too much time, so I stick to a shallow copy), but then again I have the problem of not knowing when to delete the array of data in the destructor (since I call the destructor twice and only have the data once, plus, the first call to the destructor likely comes from inserting/moving the element in the container, so I still need the array-data at that point).

I thought about using smart pointers like std::shared_ptr for the data array, but from what I have read they don't call delete [] but rather delete - which is a shame since I have an ordinary array [].

Right now I have a solution that by hand calls a "DeleteArray" function on the class before removing it from the container. It works great but.. it is not nice.

Any ideas?

Was it helpful?

Solution

Boost has a shared_array class that is like shared_ptr but will use delete[], or you can add a custom deleter to shared_ptr that will make it call delete[].

OTHER TIPS

Don't use an array, use a std::vector instead. Then point at that with a smart pointer.

Even better solution would be to put shared_ptrs to your large objects into the containers and avoid expensive copies all together.

Edit 0:

Another option, of course, is to make the objects themselves lightweight and copyable with shared_array. as Jeremiah suggests.

There is a shared_ptr equivalent for arrays, at least in the Boost libraries. It's called shared_array, and it behaves exactly as you would expect. Check out the specification at http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/shared_array.htm?sess=8940ad57baa307d68cb2e7fd2939d2db.

You can implement simple reference counting in your copy constructor. You can decrement the reference with each delete.

Many thanks for all your insightful answers!

This reminds me why the last time I had this problem I handcoded a queue without copying myself. I can't say it took me much longer than figuring out how to do the nice, clean version. :)

So.. what I did is:

Solution a) Like described in the original post, I created a function that had to be called explicitly before removing a class from the vector. Not nice but it worked great and I didn't have to mess with anything else, just remember to call it.

Solution b) I put the array in yet another class and used a smartpointer (shared_ptr) to that class. Worked really nice. I had to use shared_ptr s as elements of the vector too. (I didn't think of this at first.)

Solution c) Using shared_ptr to hold an array. Pretty bad idea as it turns out, since it calls delete instead of delete [] you need to provide your custom deleter and somehow some other (syntax) problems emerged so it took me something like 2h+ to do that solution.

It looks something like that in the header file:

 template< typename T >
  struct
array_deleter
  {
      void
    operator ()( T const * p)
      { delete[] p; }
  };

class MemoryStressChunk
{
private:
    int chunkSizeInValues;
    std::shared_ptr< __int64 > data;
};

and in the code file:

data.reset(
    new __int64[chunkSizeInValues], 
    array_deleter< __int64 >() );

and to use it I have to get it out again:

__int64 *d = data.get();

Next time I might strongly consider using the boost versions. I didn't have boost on my machine so that is why it was not an option for me.

I take it Solution d) would be to use a vector of classes containing a shared_ptr s to a vector (instead of an array). After all the fun I had with c) I did not do that on top. :)

If someone wants to have a look at the code, you can get it here http://andreas-reiff.de/wp-content/uploads/2011/01/Tool-MemTester.zip . Beware there probably is a memleak in version a) (use shared_ptr for the class as in version b) ).

Thx for all your help again!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top