Trying to understand AutoNew & AutoPtr



  • On 28/05/2013 at 16:30, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   13 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hi,
    I'm exploring these types of pointer handlers. And I don't understand how to use them.
    When I create them. I only get a very short list of same basic pointer options. Rather than the normal options I expect to see depending on the type of object I'm creating.

    Hard to explain. So I'll use a couple of visual examples:

      
    #####First comparison example#####  
    AutoAlloc<BaseBitmap> *myimage  
    myimage->       //<----------- Provides a lot of things I can use to manipulate a bitmap  
      
    AutoNew<BaseBitmap> *myimage;  
    myimage->       //<----------- Only provides a few things like Assign, Free, a few operators, etc..  
      
      
      
      
    #####Second comparison example#####  
    static PickSessionDataStruct *picksession;  
    picksession = gNew PickSessionDataStruct;  
    picksession->    //<---------- Provides things to manipulate the PickSessionDataStruct  
      
    AutoNew<PickSessionDataStruct> *picksession;  
    picksession->    //<--------- Only provides a few things like Assign, Free, a few operators, etc..
    

    Hopefully that code explains my problem.
    Both AutoNew & AutoPtr are only returning a small list of very basic pointer options. Compared to the options I'm expecting and need to get.
    I'm sure I'm using them wrong. But the SDK doesn't have any examples to learn from.

    Can anyone explain how to use these properly?
    Can/should these be used for all object types in place of Alloc and AutoAlloc. Or only in certain specific cases?

    -ScottA



  • On 28/05/2013 at 23:53, xxxxxxxx wrote:

    Hi Scott,

    AutoAlloc<> is  meant to be used with classes that implement Alloc() and Free().

    AutoNew<> can be used for classes that don't implement Alloc() and Free(). It creates objects with gNew and delete them with gDelete. It's just an easy way to automatically allocate and free objects.

    AutoPtr<> just destructs (gDelete) previously created objects with gNew.

    AutoFree<> calls Free() (at destruction or free time) on an allocated (Alloc()) object.

    AutoGeFree<> calls GeFree (at destruction or free time) on an allocated (GeAlloc()) object.

    You can see the different implementations of these templates in ge_autoptr.h.
    _
    _



  • On 29/05/2013 at 04:40, xxxxxxxx wrote:

    AutoAlloc, AutoNew are smart pointers that hide the raw pointer inside it.
    This sometimes called RAII idiom.
    Actually I would say that in C++ you should alway use smart pointers and never explicitly call delete, gDelete, ::Free(), free() or something like this.
    Of course there are some exceptions, for example if you want to write you own smart pointer or your own container.
    In my code I always use them for almost all resources.

      
        
        
        AutoAlloc<BaseBitmap> myimage; //you do not need * here !  
        myimage->Init(...);     //here you can access all BaseBitmap methods.  
        myimage.Free();      //here you can call AutoAlloc methods like Assign, Free...  
        //now myimage is internally a NULL and can not be used like this myimage->SetDirty();  
          
        AutoNew<Matrix> mymatrix; //you do not need * here !  
        mymatrix->Normalize();       //here you can call all Matrix methods.  
        mymatrix.       //here you can call AutoNew methods like Assign, Free...  
        
    

    AutoNew<Matrix> is probably bad example.

    All smart pointers in C4D are something like std::unique_ptr in new C++11.
    unique_ptr

    shared_ptr

    A bit more about smart pointers :)
    http://herbsutter.com/2013/05/28/gotw-89-smart-pointers/



  • On 29/05/2013 at 08:05, xxxxxxxx wrote:

    Oh. I see.
    I was hoping they worked with things that are allocated. Because I'm having a hard time managing bitmap memory in one of my plugins. And I thought they might help me out.
    But I guess not.

    Creating a couple of bitmap instances. Then deleting it's memory is fairly easy.
    But in my PoseLibrary plugin. The user is dynamically creating and deleting bitmap images when they save a character pose to a GeDialog Bitmap Button.
    I'm dynamically creating and deleting buttons and images. And this is proving to be a very big problem trying to figure out how to properly free the bitmap memory.
    I've gotten myself into a scenario where handling memory manually myself is a tangled nightmare.

    I'm doing all kinds of uncomfortable things. Like using a loop in my destructor with Free inside of it.
    But it's just not working properly. I keep getting either memory leakage, or not null errors when debugging it. It's nightmare.
    I was hoping that I might be able to use one of those pointer types to help me with this problem.
    But I guess not.

    Thanks for the help guys,
    -ScottA



  • On 29/05/2013 at 10:20, xxxxxxxx wrote:

    I was hoping they worked with things that are allocated.
    Yes thee are smart pointers for this too.
    AutoFree<> is probably one that you need.

      
    AutoFree<BaseBitmap>   m_bmp;  
      
    m_bmp.Assign(some_bmp);  
    


  • On 29/05/2013 at 10:31, xxxxxxxx wrote:

    Unfortunately. I can't seem to use them in my plugin.
    They tend to kill the bitmaps when I don't want to to be killed. Or just seem to work at all for what I'm doing.

    I'm sure the problem is me and my lack of memory handling experience though.
    I'm not advanced enough at handling memory to do this kind of complex dynamic creating, copying, deleting of bitmaps which are stored in arrays.
    I'm dog paddling in the deep end of the pool. 😂

    -ScottA

    Edit-- whoops.
     Misread what you wrote. I thought you referring to AutoAlloc().
     I'll give AutoFree a try and see if it helps.



  • On 29/05/2013 at 12:34, xxxxxxxx wrote:

    Based on the few times I've used it now.
    Using AutoFree does seem to work better than using BaseBitmap::Free() in my plugin.

    The other error I'm getting is this:

    void MultipassBitmap::Free(MultipassBitmap *&bm)  
    {  
      C4DOS.Bm->Free(bm);  
      bm=NULL;  
    }  
      
    First-chance exception at 0x0000000140d2ea21 in CINEMA 4D 64 Bit.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.  
    Unhandled exception at 0x0000000140d2ea21 in CINEMA 4D 64 Bit.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
    

    I know that Access violation means that I'm trying to edit something that does not exist.
    So does this mean that my code is trying to free a bitmap that it can't find?

    -ScottA



  • On 31/05/2013 at 01:21, xxxxxxxx wrote:

    There is something wrong with AutoPtr type of classes. They all lack an assignment operator.

    I guess this means that if you assign AutoPtr A to AutoPtr B and if then A goes out of scope you will get a dangling pointer in B! This is probably going to happen if you try to manage dynamic objects with AutoPtr.

    In contrast, unique_ptr moves the ownership from one pointer to the other, so A would have a NULL pointer after B = A;.

    I think what you need is std::vector<std::shared_ptr<T> > in terms of STL classes. Well this is not a solution so apologies. In R14 there is c4d_misc::PointerArray which seems just like what you need. Perhaps you can get some inspiration from there. Or you could try to use STL classes with a custom memory allocator. (I didn't just say that! ;-)



  • On 31/05/2013 at 05:06, xxxxxxxx wrote:

    There is something wrong with AutoPtr type of classes. They all lack an assignment operator.

    Yes unfortunately there is not move assignment/constructor in all this smart pointers.
    If you are aware of this limitation then it is not a problem to avoid problems with it but if not...

    There is also no safer Reset() function.
    Instead there is Set() and Assign() that you can use to override internal pointer and produce memory leak!
    I think it would be great to fix this problems in the next releases of C4D SDK.

    > Or you could try to use STL classes with a custom memory allocator. (I didn't just say that! ;-)
    Now with C++11 it is harder to not use STL any more, it is better now.


Log in to reply