8 Replies - 5102 Views - Last Post: 18 February 2009 - 11:50 AM Rate Topic: -----

#1 Darkhack  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 208
  • Joined: 25-November 08

Returning an Object - Shutting Up The Destructor

Posted 17 February 2009 - 11:58 AM

I'm working on a program for university and we're required to use a recursive function for it, so I can't use an alternative method. I need to return an object but every time I do, the destructor gets called and wipes out my memory, causing a segmentation fault. Here is what I want to do.

MyClass func()
{
	MyClass obj;
	...
	return obj;
}



The above code causes a segfault. I've found that the only way to fix it is to comment out my destructor. This leads me to believe that the destructor is being called on my obj, even though I'm returning it. Is there anyway I can NOT call the destructor in just this one instance? I can't simply keep the destructor lines commented out or it will cause memory leaks in other parts of the program.

Thank you for your help.

Is This A Good Question/Topic? 0
  • +

Replies To: Returning an Object - Shutting Up The Destructor

#2 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 854
  • View blog
  • Posts: 2,338
  • Joined: 20-August 07

Re: Returning an Object - Shutting Up The Destructor

Posted 17 February 2009 - 12:15 PM

As a general rule of thumb, if you write a class which needs either a destructor, an assignment operator, or a copy constructor, then it usually needs all 3.

What exactly does your class look like? It sounds to me as if there's a problem with your copy constructor (which will be invoked as your function returns obj
Was This Post Helpful? 0
  • +
  • -

#3 Darkhack  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 208
  • Joined: 25-November 08

Re: Returning an Object - Shutting Up The Destructor

Posted 17 February 2009 - 12:24 PM

Ahh, thank you very much. I didn't have a copy constructor at all. I'll add one and report back if that works.

Update: Nope, that wasn't it. I've never used a copy constructor before so I googled around and it appears that it's only used when you're creating a copy of an object. I'm not really doing that here. I'm just trying to return an object. It doesn't matter if I return the original object or a copy, the destructor gets called and wipes my data.

This post has been edited by Darkhack: 17 February 2009 - 12:37 PM

Was This Post Helpful? 0
  • +
  • -

#4 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3089
  • View blog
  • Posts: 19,137
  • Joined: 14-September 07

Re: Returning an Object - Shutting Up The Destructor

Posted 17 February 2009 - 01:24 PM

Does your object use any dynamically allocated memory? The snippet you posted doesn't use pointers so assuming the class doesn't either (or use 'new'/malloc(), etc...) the problem lies elsewhere. However, you mentioned a destructor, which is used for freeing memory, so we need to see a code listing to help.


edit: Instead of having a function return an object, why not make the function void, pass a pointer you want to assign to the object and go about it that way?

This post has been edited by KYA: 17 February 2009 - 01:25 PM

Was This Post Helpful? 0
  • +
  • -

#5 Darkhack  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 208
  • Joined: 25-November 08

Re: Returning an Object - Shutting Up The Destructor

Posted 17 February 2009 - 02:00 PM

View PostKYA, on 17 Feb, 2009 - 01:24 PM, said:

Does your object use any dynamically allocated memory?


Yes.

View PostKYA, on 17 Feb, 2009 - 01:24 PM, said:

we need to see a code listing to help.


It's kind of a complicated program and I'd hate to just dump a bunch of random code. I already know what the problem is thanks to GDB and Valgrind. The exact implementation isn't important.

View PostKYA, on 17 Feb, 2009 - 01:24 PM, said:

Instead of having a function return an object, why not make the function void, pass a pointer you want to assign to the object and go about it that way?


I said in my original post that I'm required to use a recursive function because it's for a class assignment.

Anyways, I have the program working just fine. The only problem is that it leaks memory and it seems like any attempt to free it (no matter where) causes a segmentation fault. I suppose it *could* be because valgrind has issues with recursive functions, but the valgrind authors claim "99% accuracy" and I'd be really surprised if something as common as recursion would throw it off.

I'll just let it leak memory (hey, at least it works) and ask my teacher for help if nobody here knows of a decent solution. I'm normally a C programmer so I'm pretty good at managing my own memory. I just think it's retarded as hell that C++ would still call the destructor even when an object is being returned. But good design was never really C++'s strong point.
Was This Post Helpful? 0
  • +
  • -

#6 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3089
  • View blog
  • Posts: 19,137
  • Joined: 14-September 07

Re: Returning an Object - Shutting Up The Destructor

Posted 17 February 2009 - 02:49 PM

The object goes out of scope, so the destructor being called makes perfect sense to me.
Was This Post Helpful? 0
  • +
  • -

#7 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 854
  • View blog
  • Posts: 2,338
  • Joined: 20-August 07

Re: Returning an Object - Shutting Up The Destructor

Posted 17 February 2009 - 03:19 PM

View PostDarkhack, on 17 Feb, 2009 - 07:24 PM, said:

Update: Nope, that wasn't it. I've never used a copy constructor before so I googled around and it appears that it's only used when you're creating a copy of an object.
That's right, but it certainly applies to your situation, even if its invisible to you

View PostDarkhack, on 17 Feb, 2009 - 07:24 PM, said:

I'm not really doing that here.
But you are - that's exactly what your function is doing when it returns "obj". it sends a copy back to the code which called the function and destroys the locally declared object.

View PostDarkhack, on 17 Feb, 2009 - 07:24 PM, said:

I'm just trying to return an object. It doesn't matter if I return the original object or a copy, the destructor gets called and wipes my data.
You cannot ever return the original object when you've declared it at function scope - the C++ language has strict lifetime rules for statically allocated objects, and there's no way whatsoever to bypass them.
As the name 'static' might suggest - the lifetime of the object is fixed to end at a predetermined point in your program - any attempts to access the object after its lifetime has expired will result in bad things - the return statement must create a copy because it can't allow you to use an object which it knows is about to die (don't try to stop a destructor being called either, that's equally as bad, possibly worse)


In summary - you are returning a shallow copy from your function. a "shallow" copy is a copy of an object where members are copied "as is". i.e., any pointers which your class is responsible for will still point to the same memory location. a "Deep" copy is where the class is copied in full - including new copies of any dynamically allocated memory, so that your class' pointer members will not be pointing to memory which it is not responsible for.

The idiom to solve this common problem is known as "RAII", and it fits perfectly around the 'rule of 3' - copy constructor/destructor/assignment operator

A typical RAII class might look like this
class myclass
{
    int* x;
public:
    myclass(const myclass& obj) : x( new int(*obj.x) ) {}
    ~myclass()
    {
        delete x;
    }
    myclass& operator= (const myclass& obj)
    {
        delete x;
        x = new int( *obj.x );
    }
};  

This post has been edited by Bench: 17 February 2009 - 03:40 PM

Was This Post Helpful? 0
  • +
  • -

#8 Darkhack  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 208
  • Joined: 25-November 08

Re: Returning an Object - Shutting Up The Destructor

Posted 17 February 2009 - 10:13 PM

Okay, I managed to figure out a solution. The first thing I did was I moved my recursive function. The function was a method of a class but instead of doing something like obj.recurse(another_obj); I decided it would be better just to have my recursive function outside of the class entirely.

The second thing I did was that I decided to ditch the destructor all together. It wasn't working at all. In fact, after I fixed my original bug, I found that the destructor was being called prematurely in other functions as well. The whole thing ended up being a mess and I just decided to write my own obj.clear() method which would basically do the exact same thing as the destructor, only I would call it manually when I knew I was truly done with the memory.

In the end, I was able to get my program working perfectly and valgrind was completely happy with it. It's a shame that I had to manage my own memory though. This is one reason I prefer C over C++ and will probably not use destructors in the future.

Thank you all for your help. I've never used a copy constructor before, but I'm glad I know what they are now for future reference. I didn't use them for my solution, but it's still good to have.
Was This Post Helpful? 0
  • +
  • -

#9 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 854
  • View blog
  • Posts: 2,338
  • Joined: 20-August 07

Re: Returning an Object - Shutting Up The Destructor

Posted 18 February 2009 - 11:50 AM

I'd be curious to see what exactly you were attempting. it sounds like you may have based your design around a misunderstanding of how objects are created and destroyed. That doesn't mean destructors are useless (and C++ is far better at automating memory management than C) - in fact, if you're in the situation of needing to allocate and clean up memory all over the place then there's probably a far better solution to your problem (One of which might be a smart pointer such as the boost::shared_ptr - which will be part of the next C++ standard)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1