Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Freeing Allocations inside of Methods?

    SDK Help
    0
    5
    362
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          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.  
            
          
          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            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

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              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

              1 Reply Last reply Reply Quote 0
              • First post
                Last post