1

Possible Duplicate:
What is The Rule of Three?

Array(const Array &arraytoCopy)
:size(arraytoCopy.size)
{
    ptr=new int[size];
    for(i=0;i<size;i++)
        ptr[i]=arraytoCopy.ptr[i];
}

what is going to happen if i don't provide a copy constructor.

Community
  • 1
  • 1
munish
  • 4,505
  • 14
  • 53
  • 83
  • 2
    The destructor should call `delete[]` on `ptr`, and if you don't have a copy constructor and you make a copy of the object, it will call `delete[]` twice on the same pointer because `ptr` is the same in both objects, and that causes undefined behaviour. That's why. – Seth Carnegie Nov 09 '12 at 06:42

3 Answers3

3

What will happen is that when you copy the object, you will have more than one instance pointing to the same dynamically allocated array. It isn't clear which instance should take care of de-allocating it upon destruction.

If the class is supposed to own the array, then it will be in charge of de-allocating its resources. In this case, it should have a copy constructor and assignment operator that make a copy of the contents of the array, plus a destructor calling delete[] on it. This is known as the rule of three. In C++11, it should also have move copy and move assignment operators too.

If the class doesn't own the array, it probably shouldn't construct it in the first place. It could receive a pointer to an externally allocated array via its constructor, for example.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • "Copy constructor's rule of three" - 1. If you manage resources, define copy constructor. 2. If you don't, define copy constructor and assignment operator as private. 3. If you don't know, do not write a class. – SChepurin Nov 09 '12 at 07:04
  • @SChepurin There are situations where a class doesn't own the resources but copying and assigning is fine. As long as they don't try to de-allocate in the destructor. – juanchopanza Nov 09 '12 at 07:13
2

As you have raw pointers to owned dynamically allocated objects in the class, you have to provide copy constructor and copy assign operator function properly.

Consider below class definition

class Array
{
public:
  Array()
  { 
     ptr = new int[10];
  }
  ~Array(){
     delete [] ptr;
  }
private:
  int *ptr;  
};

when you instantiate two object of Array:

Array a1, a2;
a1 = a2;

Now a1.ptr is pointing to the same memory address as p2.ptr during the destruction of a1, a2 the ptr memory will deleted twice which is undefined behavior.

use std::vector<int> int_collection_; is good solution instead of using raw pointer.

class Array
    {
    public:
      Array()
      {           
      }
      ~Array(){             
      }
    private:
      std::vector<int> int_collection_;
    };
billz
  • 44,644
  • 9
  • 83
  • 100
  • 1
    Minor nit-pick: it isn't about the raw pointers, but about raw pointers to owned dynamically allocated objects. – juanchopanza Nov 09 '12 at 06:56
  • yup, I agree with you. sometime we pass in raw pointer and hold it in the object is perfectly fine. :) – billz Nov 09 '12 at 06:58
0

If your intention is to not allow copying of your class instances, you may define your copy constructor as private and do not provide an implementation so that compiler can catch these cases e.g.

class Array
{
    ...
private:
    Array(const Array &arraytoCopy); // not implemented
};

In this case you don't have to worry about pointer ownership problems described above.

tommyk
  • 3,187
  • 7
  • 39
  • 61