Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2006
    Posts
    48
    Rep Power
    9

    Relase Object Memory?


    Hi,

    I got a question about releasing memory.

    The head file is like below.
    Code:
    class ReportDialog : public FindStringDialog
    {
    public:
          ReportDialog(...);
        ~ ReportDialog ();
    private:
         Object1 *pObject1;
         Object2 *pObject2;
         char	*sUser;
    }
    The Cpp file is like below.
    Code:
    ReportDialog::~ReportDialog()
    {
       delete [] sUser;
       delete pObject1;
       delete pObject2;
     }
    The problem is on "delete" pObject1 and pObject2.

    Do I nee to write "delete [] pObject1" or "delete [] pObject2"?
    Or I just leave them like above?
    If I did "delete [] pObject1" and "delete [] pObject2", the compiler did not complaint.

    Object1 and Object2 will link to some other objects which contian some variables. We could not delete them(variables) on the other objects because the values will be lost if we delete them on the other objects.

    Is it right to do "delete [] pObject1"?



    Thank you!
  2. #2
  3. Commie Mutant Traitor
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Jun 2004
    Location
    Norcross, GA (again)
    Posts
    1,804
    Rep Power
    1569
    Using the square brackets after delete is meant for de-allocating arrays; while using it with a single object isn't wrong, it isn't necessary, either, and has additional overhead as it checks the array size (which in this case is of course one).

    However, it sounds to me as if what you really need is to define destructors for your classes Object1, Object2, etc. which de-allocate any dynamically allocated instance variables. Then when you use delete on the objects, it should automatically call the dtor before freeing the object itself. For example, if class MyObject defines a pointer to an array of int's named intvectorwhich it allocates over the lifetime of the object, you would want a dtor like this:
    C++ Code:
    ~MyObject()
    {
        delete [] intvector;
    }


    You would want to do this with any class that requests system resources (memory, semaphores, file locks, TCP ports, etc.), to ensure those resources get appropriately released.

    References:
    Frank and Jake’s destructors:

    [EDIT: corrected some minor typos.]
    Last edited by Schol-R-LEA; May 22nd, 2006 at 07:30 PM.
    Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
    #define KINSEY (rand() % 7) λ Scheme is the Red Pill
    Scheme in ShortUnderstanding the C/C++ Preprocessor
    Taming PythonA Highly Opinionated Review of Programming Languages for the Novice, v1.1

    FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2006
    Posts
    48
    Rep Power
    9
    Schol-R-LEA,

    Thank you for your clear explanation.
  6. #4
  7. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,592
    Rep Power
    4207
    Originally Posted by Schol-R-LEA
    However, it sounds to me as if what you really need is to define a destructors for your classes Object1, Object2, etc. which de-allocate any dynamically allocated instance variables. Then when you use delete on the objects, it should automatically call the dtor before freeing the object itself. For example, if class MyObject defines a pointer to an array of int's named intvectorwhich it allocates over the lifetime of the object, you would want a dtor like this:
    C++ Code:
    ~Myobject()
    {
        delete [] intvector;
    }


    You would want to do this with any class that requests system resources (memory, semaphores, file locks, TCP ports, etc.), to ensure those resources get appropriately released.

    References:
    Frank and Jake’s destructors:
    Be VERY VERY careful when doing this. If not properly coded, you could get mysterious errors. Here's Ol' Scorpy's puzzle of the week -- the below code is a programmer's attempt to make a "safe array" class. However, there is a hidden problem just waiting to occur. Your assignment is to figure out what it is and how you would fix it. First person to solve it gets their name in my signature for a week.
    Code:
    #include <iostream>
    using namespace std;
    
    class MyObject {
    private:
        int *a;
        size_t num;
    
    public:
        MyObject::MyObject(size_t x);
        MyObject::~MyObject();
        size_t MyObject::GetSize(void);
        int MyObject::GetValue(size_t n);
        void MyObject::SetValue(size_t n, int x);
    };
    
    MyObject::MyObject(size_t x)
    {
        num = x;
        a = new int[num];
    }
    
    MyObject::~MyObject()
    {
        delete [] a;
    }
    
    size_t MyObject::GetSize(void)
    {
        return num;
    }
    
    int MyObject::GetValue(size_t n)
    {
        if (n >=0 && n < num)
            return a[n];
        else
            return 0;
    }
    
    void MyObject::SetValue(size_t n, int x)
    {
        if (n >=0 && n < num)
            a[n] = x;
    }
    
    int main(void)
    {
        MyObject array(10);
        for (int i = 0; i < 10; i++)
            array.SetValue(i, i);
        for (int i = 0; i < array.GetSize(); i++)
            cout << array.GetValue(i) << endl;
    
        return 0;
    }
    Last edited by Scorpions4ever; May 23rd, 2006 at 08:37 AM.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  8. #5
  9. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,592
    Rep Power
    4207
    HINT: Try to make a function to print all the values of a MyObject. The function should accept MyObject by value and print all the values in it.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  10. #6
  11. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,905
    Rep Power
    3969
    When you pass by value, and the function returns it'll call the destructor which free's the memory even though there's still references to that memory block via the instance(s) in the calling function(s).

    I actually had to help someone diagnose that exact problem about two weeks ago. Their C++ instructor gave them a dynamic array class similar to what you just posted and wanted them to write a recursive function to search the array for a value. They passed by value into the search function and were having problems with the code. Had them change it to pass-by-ref and it all worked fine.
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2006
    Posts
    48
    Rep Power
    9
    The answer is on the color Dark Green.

    Originally Posted by Scorpions4ever
    Code:
    #include <iostream>
    using namespace std;
    
    class MyObject {
    private:
        int *a;
        size_t num;
    
    public:
        MyObject::MyObject(size_t x);
        MyObject::~MyObject();
        size_t MyObject::GetSize(void);
        int MyObject::GetValue(size_t n);
        void MyObject::SetValue(size_t n, int x);
    };
    
    MyObject::MyObject(size_t x)
    {
        num = x;
        a = new int[num];
    }
    
    MyObject::~MyObject()
    {
        delete [] a;
    }
    
    size_t MyObject::GetSize(void)
    {
        return num;
    }
    
    int MyObject::GetValue(size_t n)
    {
        if (n >=0 && n < num)
            return a[n];
    
        return 0;
    }
    
    void MyObject::SetValue(size_t n, int x)
    {
        if (n >=0 && n < num)
            a[n] = x;
    }
    
    int main(void)
    {
       int i;
    
        MyObject array(10);
        for (i = 0; i < 10; i++)
            array.SetValue(i, i);
        for (i = 0; i < array.GetSize(); i++)
            cout << array.GetValue(i) << endl;
    
        return 0;
    }
  14. #8
  15. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,592
    Rep Power
    4207
    david23: Not even close. The one reason you might need to declare i outside the for loop is if you are using VC++ 6.0 which isn't quite compliant with the latest C++ standards.

    Kicken: You did identify the issue correctly :). For that effort, your name appears on my sig for partial credit. However, there is a better fix for it. You cannot guarantee that anyone using your object will always pass by reference. To know to pass by reference, they'll have to see the internals of your object and that defeats the purpose of OO. There's another fix to it that gets around people passing the object by value.

    For those that are wondering what Kicken and I are talking about, consider the following code:
    Code:
    void PrintObject(MyObject foo)
    {
       for (int i = 0; i < foo.GetSize(); i++)
           cout << foo.GetValue(i) << endl;
    }
    
    int main(void) 
    {
    ...
        for (int i = 0; i < 10; i++)
            array.SetValue(i, i);
        PrintObject(array);
        array.SetValue(1, 5); // <-- Now array is invalid and code should burp
    The reason for the failure is because when you pass by value, foo's destructor gets called when PrintObject exits. Since foo.a points to array.a, you cannot access array.a's elements any longer.This should give you a hint as to how to fix the object so this doesn't occur.
    Last edited by Scorpions4ever; May 23rd, 2006 at 03:58 PM.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2004
    Posts
    153
    Rep Power
    11
    Reference count?
  18. #10
  19. Super User
    Devshed Novice (500 - 999 posts)

    Join Date
    Sep 2004
    Posts
    648
    Rep Power
    75
    Originally Posted by kk3z
    Reference count?
    I don't think so, when you pass an object by value the constructor isn't called again, thus you couldn't keep track of the reference count in this case.
  20. #11
  21. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,592
    Rep Power
    4207
    Nope... Keep trying folks. Would you guys like another hint?
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  22. #12
  23. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,905
    Rep Power
    3969
    I tend to just work with C rather than C++ so I'm not really up to snuff with the C++ OO stuff, but I would guess the solution lies somewhere with using the copy constructor. Just not sure what one would do (besides copy the allocated memory aswell, which seems a bit wasteful).
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  24. #13
  25. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,592
    Rep Power
    4207
    Originally Posted by kicken
    I tend to just work with C rather than C++ so I'm not really up to snuff with the C++ OO stuff, but I would guess the solution lies somewhere with using the copy constructor. Just not sure what one would do (besides copy the allocated memory aswell, which seems a bit wasteful).
    You're pretty close to the solution :). Note that there are actually a couple of ways to handle this and both have been mentioned in this thread. Just put all the stuff that's been mentioned in this thread together and you'll have the correct solution(s).
    Last edited by Scorpions4ever; May 25th, 2006 at 01:52 AM.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2006
    Posts
    10
    Rep Power
    0
    By preventing to pass by value: declare a copy-constructor private.

    Or just add a function that will delete a, and the object.

    Code:
    MyObject::DeleteObject()
    {
        delete [] a;
        delete this;
    }
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    433
    Rep Power
    10
    Wouldn't the fix be to pass a pointer to the object?:
    Code:
    void PrintObject(MyObject * foo);
    In main():
    Code:
    PrintObject(&foo);
    This is what I always do to avoid such a problem.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo