0

I also have some errors with copy constructor that I cant figure out, but the main question at the moment is brought out in my test programs comments. Why is the second print out so big number, and not three? Thank in advance for your help.

template<class T>
class Array {
    private:
        T *cont;
        unsigned int size;

    public:

    Array()=default;


    T& elementAt(unsigned int i)
    {
    return cont[i]; 
    }


    Array( const Array &a ) 
    {
    cont = new int[ size ];

    for ( int i = 0; i < size; i++ )
        cont[ i ] = a.cont[ i ];
    }


    Array& operator = (const Array& a)
    {
    int i,min_size;
    if(size < a.size)
        min_size = size;
    else
        min_size = a.size;
    for(i=0; i<min_size; i++)
        cont[i] = a.cont[i];
    return (*this);
    }


    void addElement(T element) {
        T *new_cont = new T[size + 1], *old_cont = cont;

        for (int i = 0; i < size; i++) {
            new_cont[i] = old_cont[i];
        }

        new_cont[size] = element;
        size++;

        cont = new_cont;
        delete old_cont;
    }


    unsigned int getSize() const
    {
    return size;
    }


    ~Array()
    {
    delete [] cont;
    }



};

And this part of my test program:

Array<int> numbers;             
    numbers.addElement (5);         
    numbers.addElement (11);        
    numbers.addElement (3);
        cout << numbers.getSize()<<endl;  // Here I get output: 3
    cout<< numbers.elementAt(1)<<endl; // output: 11
        MyArray<int> copy2;
    copy2 = numbers;    
        cout << copy2.getSize()<<endl;  //  WHY is output: 2686697, in here? Why isn' t it 3.
    cout<< copy2.elementAt(1)<<endl; // output: 11
user3328230
  • 61
  • 1
  • 9

3 Answers3

1

At the time you call your copy constructor, the size member is uninitialized. You probably meant

 size = a.size; // Initialize size member also, it's not done automagically
 cont = new int[ size ]; 

in your copy constructor.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
0

You should get size from object a

Array( const Array &a ) 
{
    cont = new int[ a.size ];

    for ( int i = 0; i < a.size; i++ )
        cont[ i ] = a.cont[ i ];
}
AdamF
  • 2,501
  • 17
  • 30
  • 1
    Better yet: add `size = a.size;` at the first line. – barak manos Apr 06 '14 at 19:24
  • Thank you, for your answer. I have one further question. cont = new int[ a.size ]; should I maybe use some other type than int if I want my class to be template. I am sorry if this is stupid question. Maybe cont = new T[a.size] ? – user3328230 Apr 06 '14 at 19:26
  • Yes for templates you should use T like: cont = new T[ a.size ]; – AdamF Apr 06 '14 at 19:33
  • Somehow it is still giving the same random size. I think that maybe I was not using copy constructor in my testing program. Instead maybe this (Array& operator = (const Array& a)) So I tried to use line to use copy constructor: Array copy = numbers; it compiles, but when I run the program it crashes, and does not give any error. – user3328230 Apr 06 '14 at 19:40
0

You are using the wrong size to allocate memory in the copy constructor.

Array( const Array &a ) 
{
  // Get the size from the copy first. Without it, size is an unitialized
  // value, which will lead to undefined behavior.
  size = a.size;
  cont = new int[ size ];

  for ( int i = 0; i < size; i++ )
    cont[ i ] = a.cont[ i ];
}

The other problem that I see is the implementation of the default constructor. The default constructor can be used in two ways:

Array<int> numbers;

or

Array<int> numbers = Array<int>();

The former will result in uninitialized data while the latter will result in properly initialized data with your implementation. See details here.

You can change the default constructor to:

Array() : size(0), cont(NULL) {}

to make your code work identically in either way of constructing the object.

The third problem is the operator= function. It does not perform a true assignment. It only stores the minimum number of elements from the two objects. Try this:

   Array& operator = (const Array& a)
   {
      // Make statements like 'a = a;' a noop.
      if ( this != &a )
      {
         // If the size of the LHS is larger than or equal to the size
         // of the RHS, the LHS has enough memory to store the data
         // from the RHS.
         if ( this->size >= a.size )
         {
            this->size = a.size;
            for(int i=0; i<a.size; i++)
               cont[i] = a.cont[i];
         }
         else
         {
            // The size of the LHS is smaller than the size of the RHS,
            // It does not have enough memory to store the data from
            // the RHS. Dellocate old memory. Allocate new memory.
            // Then copy the data.
            this->size = a.size;
            delete [] cont;
            cont = new int[this->size];
            for(int i=0; i<a.size; i++)
               cont[i] = a.cont[i];

         }
      }
      return (*this);
   }
Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Somehow it is still giving the same random size. I think that maybe I was not using copy constructor in my testing program. So I tried to use line: Array copy = numbers; it compiles, but when I run the program it crashes, and does not give any error. – user3328230 Apr 06 '14 at 19:34
  • @user3328230 I updated my answer to address another problematic piece of code. Hopefully that will solver your problems. – R Sahu Apr 06 '14 at 19:42
  • It is probably my own fault, but I still can't get it to work properly. I think your version of the copy constructor is correct, but my: Array& operator = (const Array& a) has an error maybe. Could I be wright ? I saw that somebody used a similar line in his program: Array copy = numbers; I intend to make copy named "copy" of array named "numbers". So I am not allowed to use it like that? It seemed to work for him. – user3328230 Apr 06 '14 at 19:57