Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Re: Destructors can copying objects (http://www.velocityreviews.com/forums/t746317-re-destructors-can-copying-objects.html)

Yannick Tremblay 04-04-2011 12:56 PM

Re: Destructors can copying objects
 
On 2011-04-02, Ruben Safir <ruben@mrbrklyn.com> wrote:
>
> I am creating a linked link program which created a segmentation fault
> and a core at the end of the program. The program is trying to delete an
> already deleted object, and I can't seem to protect my program from
> this. I fixed the problem by sending an object to a function by
> reference rather than by value, but I'm not satisfied with the solution.
>
> The list has node objects
>
> namespace chainlist {
>
>
> /*
> *
>================================================= ====================
> * Class: Node
> * Description: This is a node in the "List" Link List
> *
>================================================= ===================
> */
>
> template < class unk >
> class Node
> {
> public:
>
> // ==================== LIFECYCLE =======================================
> /* constructor */
> Node<unk>( unk value, Node<unk> *item_to_link_to = 0);
> Node ( const Node &other ); /* copy constructor - Need to write this! */


Stop here!

Could you clarify to us why the following comments is there:
/* copy constructor - Need to write this! */


Yannick

Yannick Tremblay 04-05-2011 11:36 AM

Re: Destructors can copying objects
 
On 2011-04-04, Ruben Safir <ruben@mrbrklyn.com> wrote:
> On Mon, 04 Apr 2011 12:56:41 +0000, Yannick Tremblay wrote:
>
>>> ======================================= /* constructor */
>>> Node<unk>( unk value, Node<unk> *item_to_link_to = 0); Node ( const
>>> Node &other ); /* copy constructor - Need to write this! */

>>
>> Stop here!
>>
>> Could you clarify to us why the following comments is there: /* copy
>> constructor - Need to write this! */

>
> Because I haven't written it yet.
>
> The purpose of the question is to understand what is happening, not to necessarily
> fix the program. This is not a homework assignment with a deadline. I just want to
> have a better understanding of why the destructor caused a double delete.


This was a leading question.

copy-constructor are not always needed for all classes. However, for
some classes a copy constructor is absolutely needed.

Here you have a header file that explicitely says (correctly given the
your class contains raw pointers) that the copy contructor need to be
written. I am not sure if you wrote it yourself as a reminder or if
it was a format that was specified externally from a template that
attempt to remind peoples that they should write copy-constructors.

Regardless, despite the presence of this reminder, you have not
written the copy-constructor. That should very probably be your first
point of call.

Your destructor cause double delete because your copy constructor and
your destructor are incompatible. Write a copy-constructor that is
compatible with your destructor or write a copy-constructor and modify
your destructor so both are compatible and you will not have a bug
anymore.

So essentially you have a Node that contains a pointer to value and a
pointer to next. You have a destructor that delete the pointer to
value.

What currently happens if you copy a node?
(hint: compiler generated copy constructor)
(hint: what will be the values of value_ and next_ in the copy and in
the original?)

What will happen if you delete this node copy?

What will happen if you delete the original node?


Yannick

Drew Lawson 04-05-2011 01:02 PM

Re: Destructors can copying objects
 
In article <indbq3$r87$2@reader1.panix.com>
Ruben Safir <ruben@mrbrklyn.com> writes:

>The purpose of the question is to understand what is happening, not to necessarily
>fix the program. This is not a homework assignment with a deadline. I just want to
>have a better understanding of why the destructor caused a double delete.


Others will cover (or have covered) the language intricacies.
The practical apect of that question is roughtly:

Your class Foo has a member
Bar* ptr;
The destructor does
delete ptr;

If you let the compiler generate the copy constructor and do this:
Foo a; // assuming ptr points to valid allocated memory
Foo b;
b = a;
The default copy constructor will copy a.ptr to b.ptr, because a
pointer is just a bunch of bytes.

When a.~Foo() runs, a.ptr is deleted.
When b.~Foo() runs, b.ptr, which is the same as a.ptr and was already
deleted, gets deleted.

So, if the primitive types in the object have more meaning than
just "a bunch of bytes," you probably need to write the copy
constructor (and operator=), or prevent copying.

--
Drew Lawson | Savage bed foot-warmer
| of purest feline ancestry
| Look out little furry folk
| it's the all-night working cat

Sana 04-05-2011 05:11 PM

Re: Destructors can copying objects
 
On Apr 5, 11:40*am, Ruben Safir <ru...@mrbrklyn.com> wrote:
>
> But I'm distressed at this point because I don't want two copies of all
> the nodes. *I want one series of nodes, which are created in free memory
> on the stack, handled in all possible scopes. *The nodes themselves are
> 'self aware" of their positions in the list in that they have the
> information of they're position in the nodes. *The List object itself
> does nothing more that communicate with the nodes. *If I copy the List
> Object, I don't want to duplicate the nodes as well. *They're on the
> heap, and then can stay there.
>


Make your copy constructor private. This will forbid passing the list
by value. So you will have to pass the list by reference.

/d

Volker Lukas 04-05-2011 05:21 PM

Re: Destructors can copying objects
 
Ruben Safir wrote:
....
> But I'm distressed at this point because I don't want two copies of
> all
> the nodes. I want one series of nodes, which are created in free
> memory
> on the stack, handled in all possible scopes. The nodes themselves
> are 'self aware" of their positions in the list in that they have the
> information of they're position in the nodes. The List object itself
> does nothing more that communicate with the nodes. If I copy the List
> Object, I don't want to duplicate the nodes as well. They're on the
> heap, and then can stay there.

In this case, you could split your List class in a frontend and a
backend. The frontend stores a e.g. a shared_ptr to the backend and
forwards all functions like insert, remove, ... to the backend class. Or
you could just use a non-copyable List class and have all users of this
class use shared_ptrs directly. Something like this (untested):

class List {
List& operator=(List const&);
List(List const&);

public:
static shared_ptr<List> make() { return shared_ptr<List>(new List); }

// Rest of implementation here...
};


Yannick Tremblay 04-06-2011 11:12 AM

Re: Destructors can copying objects
 
On 2011-04-05, Ruben Safir <ruben@mrbrklyn.com> wrote:
>
> But I'm distressed at this point because I don't want two copies of all
> the nodes. I want one series of nodes, which are created in free memory
> on the stack, handled in all possible scopes. The nodes themselves are
> 'self aware" of their positions in the list in that they have the
> information of they're position in the nodes. The List object itself
> does nothing more that communicate with the nodes. If I copy the List
> Object, I don't want to duplicate the nodes as well. They're on the
> heap, and then can stay there.


Are you sure about the behaviour you want?

You have a List.
The list contains Nodes.
The Nodes contain a pointer to some data.

What behaviour do you want when you copy a list?

What behavious do you want when you copy a node?

What behaviour do you want when you destroy a list?

What behaviour do you want when you destroy a node?

Don't worry about optimization for now. Worry about correctness and
consistency.

Does the Node own the data it points to?
- If yes: then the node most delete the data when the node gets
destroyed
- If no: the node only refers to the data that is external. The node
can go away without affecting the data. Lifetime management of the
data is done separately.

Should modifying a copy of a list affect the original list?
List list1;
// add ten element to list1;
assert(list1.size() == 10);
List list2 = list1; // Create a copy
assert(list2.size() == list1.size()); // definite at this point

// remove 2 element from list2
assert(list2.size() == 8);

// What about list1? Should it still contain 10 elements or 8?

Does the list owns the nodes it contains?

etc.



All times are GMT. The time now is 10:11 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.