Thread: C++ Multiple Calls to Destructor

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    102

    C++ Multiple Calls to Destructor

    Hey all,

    I'm currently working on creating a resource management system for use in my own projects.

    My original idea was to prevent loading a resource multiple times into memory. For Example: Two objects both need to draw the same image;

    I tried to set this functionality up by overriding new and delete.
    When a resource is dynamically allocated, it checks to make sure that resource doesn't already exist. If it does, it returns the address of the already existing resource. Otherwise it returns allocated memory.

    Obviously I have run into a lot of little tricks with Constructors and initializer lists overwriting already loaded resources, but it works mostly to my liking.

    I overwrite the delete to only free the memory if the resource has no more objects referring to it. My current and only issue is that after calling delete and the 'images' destructor from an instance. Any other references to deleting that 'image' do not call the 'images' destructor.

    Code:
    Image* x = new Image("File1");
    Image* x2 = new Image("File1");
    
    // At this Point, x == x2 due to overridden new operator; they reference same file.
    
    delete x;  // Calls ~Image() , doesn't free memory for the image
    delete x2; // Does not Call ~Image(), does free memory for the image
    
    // Reversing the order, yields the same result. x2 will call the destructor, x will not.
    I know there are a lot of wrong practices going on here, but I'm ok with that. Can anyone tell me if a destructor physically marks an object as not being 'that type of object' or something similar?
    Last edited by JJFMJR; 09-20-2011 at 10:51 PM.
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Are you trying to write a limited garbage collector, or something closer to a smart pointer?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    102
    Actually it doesn't really compare effectively to either. I'm trying to create an easy functionality for me to keep track of the resources I use in my projects.

    The concept is simple: Before we allocate a new resource, make sure we haven't already loaded it. If we haven't, make it; else use the already loaded resource.
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I would stick to something like reference counting. If your overridden delete and new operators do that, then you should have no problem keeping track of an Image resource or whatever. And it shouldn't matter what the destructor does as long as delete calls it on time (0 references). Default destructors, in fact, do nothing.

    edit - Although I would make the constructors private to avoid circumventing the reference counting.

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    102
    Quote Originally Posted by whiteflags View Post
    I would stick to something like reference counting. If your overridden delete and new operators do that, then you should have no problem keeping track of an Image resource or whatever. And it shouldn't matter what the destructor does as long as delete calls it on time (0 references). Default destructors, in fact, do nothing.

    edit - Although I would make the constructors private to avoid circumventing the reference counting.
    Thanks for the reply.

    That's essentially what it does; my concern was any memory that needs to be free in a Resource destructor. For instance if my image has an array of pixel data. I need to delete the pixel data which would be handled within the destructor. There's work arounds, but I would really like to figure out why I am unable to call the destructor of an object twice if I don't release the memory.
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Maybe what you could do is this: create a resource registry singleton. Whenever you want to access one of these resources, you pass whatever information is required to the registry, and receive a shared pointer to the resource. The registry itself checks if the lookup information has already been stored, and if so, refers to the corresponding weak pointer. If the weak pointer is expired (or if the lookup information has not been stored, i.e., very first access ever), it creates the resource, stores a weak pointer to it, and returns a corresponding smart pointer. Otherwise, it simply returns a smart pointer from the weak pointer.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    If the weak pointer is expired (or if the lookup information has not been stored, i.e., very first access ever), it creates the resource
    There is one case where this might not work. What if the resource system needs to return a default resource instead of creating one? If it is an on demand resource system then it would load the resource but there could be times when say a default resource could be used to notify the user that the requested resource does not exist. This is great for texture resources in graphics systems b/c when you see the default resource pop up you know exactly what has happened. Obviously the answer depends on the requirements and design of the system.

    However the resource system that laserlight has so graciously described in great detail is a common design and it works just fine. The simplest answer if you do not want to go through all of that is what whiteflags post talks about. You can use reference counting to keep track of how many refs are floating around out there in space. You can code this on your own which I do not recommend since there are about a million ways to incorrectly code a ref counted object. Besides Boost shared pointers and weak pointers offer the same functionality and you don't ever have to maintain the code behind them which is another win. Boost is free which is also a win. It looks like Boost is a win-win situation here.
    Last edited by VirtualAce; 09-20-2011 at 11:20 PM.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by VirtualAce
    Boost shared/weak pointers are a lifesaver and since Boost is free it's a win-win situation.
    Also, shared and weak pointers are now part of the C++ standard library, and before that, part of the TR1 extensions to the standard library.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    102
    Thanks LaserLight and Ace.

    I definitely see this type or resource controlling working well. I could probably implement something similar without a ton of work. The issue however is still the fact that my problem is unresolved.

    Do either of you have any idea of why my interpretation is behaving as explained? Obviously getting it to work is important, but also learning from what I've done helps even more haha.
    My Favorite Programming Line:
    Code:
    #define true ((rand() % 2) ? true : false)

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I don't think we can tell from what you have posted. If you want an answer to that, I believe you need to post the smallest possible compilable example.
    The approach to this problem is wrong, I do believe, but you've been told that already.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 08-29-2011, 01:35 PM
  2. for loop that calls multiple functions
    By elsparko in forum C++ Programming
    Replies: 2
    Last Post: 12-14-2009, 07:10 AM
  3. Replies: 4
    Last Post: 04-28-2008, 04:13 PM
  4. multiple packets received between recvfrom calls
    By ufsargas in forum Networking/Device Communication
    Replies: 4
    Last Post: 06-30-2006, 08:03 AM
  5. pure virtual calls in destructor
    By FillYourBrain in forum C++ Programming
    Replies: 2
    Last Post: 08-21-2003, 08:31 AM

Tags for this Thread