shtuken shtuken - 1 month ago 13
C++ Question

Deep or Shallow Copy when Inserting Data to a Data Structure?

I had my tree's insert function create a new Node that contains a deep copy of the data parameter.

Block 1:

insert(Object* toInsert){
...
Node temp;
temp->data = new Object(*toInsert); //deep copy toInsert
...
}


I figured this was the more solid implementation because it avoids privacy leaks. However, this resulted in a memory leak because another component (given by the prof.), does not delete the Objects it passes to insert(). My destructor would deallocate Nodes correctly, but not the original data passed to insert().

I fixed the memory leak by changing my code to Block 2.

Block 2:

insert(Object* toInsert){
...
Node temp;
temp->data = toInsert; //directly toInsert to data
...
}


I thought of a third solution, but decided my insert function should not manage another component's memory.

Block 3:

insert(Object* toInsert){
...
Node temp;
temp->data = new Object(*toInsert); //deep copy toInsert
delete toInsert; //manages another component's memory
...
}


My gut tells me Block 3 is a no-go. Am I correct?

When dealing with data structures is it better to insert data directly like in Block 2 or to make a deep copy like in Block 1?

Thanks

Answer

Select the signature of your interface functions so that that their treatment of the arguments with respect to ownership transfer is unequivocal.

For option 1, where the function copies the input argument, pass the object by (const) reference rather than through a pointer:

insert(const Object& toInsert){
    ...
    Node temp;
    temp->data = new Object(toInsert); //deep copy toInsert
    ...
}

For option 2, where the function assumes ownership of the argument object, pass the object through a std::unique_ptr:

insert(std::unique_ptr<Object> toInsert){
    ...
    Node temp;
    temp->data = toInsert.release();
    ...
}

Option 3 doesn't make sense.