Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std vector C++ -- deep or shallow copy

I wonder whether copying a vector I am copying the vector with its values (whereas this is not working with array, and deep copy need a loop or memcpy).

Could you hint to an explanation?

Regards

like image 878
kiriloff Avatar asked Jul 05 '12 16:07

kiriloff


People also ask

Does STD Vector deep copy?

5) std::copy() function And yes, it does a deep copy.

What is deep copy and shallow copy in C?

A shallow copy in this particular context means that you copy "references" (pointers, whatever) to objects, and the backing store of these references or pointers is identical, it's the very same object at the same memory location. A deep copy, in contrast, means that you copy an entire object (struct).

Does Push_back make a deep copy?

It does not make deep copies, since cv::Mat 's are shared pointers. You have to use clone() or similar when adding to the vector images .

What is the difference between shallow copy and deep copy?

Shallow Copy stores the references of objects to the original memory address. Deep copy stores copies of the object's value. Shallow Copy reflects changes made to the new/copied object in the original object. Deep copy doesn't reflect changes made to the new/copied object in the original object.


2 Answers

You are making a deep copy any time you copy a vector. But if your vector is a vector of pointers you are getting the copy of pointers, not the values are pointed to

For example:

std::vector<Foo> f; std::vector<Foo> cp = f; //deep copy. All Foo copied  std::vector<Foo*> f; std::vector<Foo*> cp = f; //deep copy (of pointers), or shallow copy (of objects). //All pointers to Foo are copied, but not Foo themselves 
like image 53
Andrew Avatar answered Sep 19 '22 15:09

Andrew


Vector will resize to have enough space for the objects. It will then iterate through the objects and call the default copy operator for every object.

In this way, the copy of the vector is 'deep'. The copy of each object in the vector is whatever is defined for the default copy operator.

In examples... this is BAD code:

#include <iostream> #include <vector>  using namespace std;  class my_array{ public:     int *array;     int size;     my_array(int size, int init_val):size(size){         array = new int[size];         for(int i=0; i<size; ++i)             array[i]=init_val;     }     ~my_array(){         cout<<"Destructed "<<array[0]<<endl;         if(array != NULL)             delete []array;         array = NULL;         size = 0;     }  };  void add_to(vector<my_array> &container){     container.push_back(my_array(4,1)); }  int main(){      vector<my_array> c;     {         my_array a(5,0);         c.push_back(a);     }     add_to(c);     //At this point the destructor of c[0] and c[1] has been called.     //However vector still holds their 'remains'     cout<<c[0].size<<endl; //should be fine, as it copies over with the = operator     cout<<c[0].array[0]<<endl;//undefined behavior, the pointer will get copied, but the data is not valid     return 0; } 

This is BETTER code:

#include <iostream> #include <vector>  using namespace std;  class my_array{ public:     int *array;     int size;     my_array(int size, int init_val):size(size){         cout<<"contsructed "<<init_val<<endl;         array = new int[size];         for(int i=0; i<size; ++i)             array[i]=init_val;     }     my_array(const my_array &to_copy){         cout<<"deep copied "<<to_copy.array[0]<<endl;         array = new int[to_copy.size];         size = to_copy.size;         for(int i=0; i<to_copy.size; i++)             array[i]=to_copy.array[i];     }      ~my_array(){         cout<<"Destructed "<<array[0]<<endl;         if(array != NULL)             delete []array;         array = NULL;         size = 0;     }  };  void add_to(vector<my_array> &container){     container.push_back(my_array(4,1)); }  int main(){      vector<my_array> c;     {         my_array a(5,0);         c.push_back(a);     }     add_to(c);     //At this point the destructor of c[0] and c[1] has been called.     //However vector holds a deep copy'     cout<<c[0].size<<endl; //This is FINE     cout<<c[0].array[0]<<endl;//This is FINE     return 0; } 
like image 22
Christian Sarofeen Avatar answered Sep 21 '22 15:09

Christian Sarofeen