Freeing Allocations inside of Methods?
-
On 17/06/2013 at 18:01, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 13
Platform: Windows ;
Language(s) : C++ ;---------
Hi,
As I learn more and more about handling memory in these plugins. I noticed something that is causing memory leaks for me. And I don't know how to correct it.To to populate a class member GeDynamicArray with several unique bitmap images. I am using a custom method that renders the image and pushes the image into to that array.
The method has the Alloc inside of it. So it is creating a brand new image every time it's called.
I guess you could say that my method is behaving similar to a class.
It's working well for the most part. And creating an array of images as I expected.But here's the problem:
When it comes time to free the memory used by these allocations. I can't.
I don't know where these allocations are. And I'm wondering if they might possibly be on the stack?
So how do I free all of those instance I've allocated from my custom method?I'm also wondering if there's maybe a better way to create an array of images than how I'm doing it with a method?
I get the feeling the way I'm doing it is very bad.-ScottA
-
On 18/06/2013 at 00:47, xxxxxxxx wrote:
Presumably when you add an image to the array, what you are adding is a pointer to a bitmap? If so, when the time comes to clean up, just call BaseBitmap::Free() on each pointer in the array, then call GeDynamicArray::FreeArray().
Steve
-
On 18/06/2013 at 03:57, xxxxxxxx wrote:
IMHO if you call Free() manually then you can forget it and will have memory leaks.
It is better to use RAII Idiom to free resources/memory.If you use C++11 then this is one way to do this.
namespace cpp11 { template <typename TYPE> class AutoFree { TYPE *ptr; private: const AutoFree<TYPE>& operator = (const AutoFree<TYPE> &p); AutoFree(const AutoFree<TYPE> &p); public: AutoFree() { ptr = nullptr; } AutoFree(TYPE* p) { ptr = p; } #ifdef _HAS_MOVE_CONSTRUCTOR //USING_CPP_11 AutoFree(AutoFree&& other) : ptr(other.Release()) {} // move constructor AutoFree& operator=(AutoFree&& other) { if (this != &other){ Reset(other.Release()); } return (*this); } // assign by moving #endif ~AutoFree() { TYPE::Free(ptr); ptr = nullptr; } void Free() { TYPE::Free(ptr); ptr = nullptr; } operator TYPE* () const { return ptr; } operator TYPE& () const { return *ptr; } TYPE *operator -> () const { return ptr; } TYPE *const *operator & () const { return &ptr; } TYPE* Get() { return ptr; } TYPE *Release() { TYPE *tmp=ptr; ptr=nullptr; return tmp; } void Reset(TYPE *p = nullptr) { if(ptr != p){ Free(); ptr=p; } } }; } //namespace cpp11
{ typedef cpp11::AutoFree<BaseBitmap> BaseBitmapRAII; c4d_misc::BaseArray< BaseBitmapRAII > bittmap_array; bittmap_array.Append( BaseBitmap::Alloc() ); } //all the BaseBitmap's will be destroyed here.
-
On 18/06/2013 at 08:47, xxxxxxxx wrote:
@Steve,
I've been trying to do that Steve. But I'm having trouble with it.
As long as I only Push() new bitmaps to the GeDynamicArray. That seems to work OK.
But if at any time I alter the array using functions like: Insert(), Remove(), etc... Then my freeing loop does not work anymore.My destructor code:
for(LONG i=0; i<images.GetCount(); i++) { BaseBitmap::Free(images[i]); }
I think maybe what's happening is when I do something to the array like using Remove(). The pointer linkage between the array and the bitmap is now broken. So now freeing the array no longer frees that bitmap anymore. And I get a memory leak.
So the problem is where is that bitmap residing that I just un-linked from the array?
And how do I free it?-ScottA
-
On 18/06/2013 at 09:04, xxxxxxxx wrote:
Doh!
After reading what I just wrote. The answer just popped out at me.I have been doing this:
Remove(i)
FreeArray(i)What I need to do is this:
FreeArray(i)
Remove(i)In other words.
I need to free the bitmap locally in my code first. Before I delete it from the array with Remove().
I can't just free it all in the destructor. That only works for bitmaps declared as class members.-ScottA