Thread: Newbie trying to figure out copy constructors

  1. #1
    Registered User
    Join Date
    Dec 2013
    Location
    Oregon
    Posts
    7

    Newbie trying to figure out copy constructors

    I am trying to figure out copy constructors for a dynamic array and I am definitely missing something. If I go into the copy constructor routine during debug, the values appear to be correct but they don't percolate up to the newly created object. I'll post a portion of the code below:

    Code:
    // include header files for the classes that are being used
    #include "stdafx.h"       //NOTE:  THis reference must be added to all cpp files in Visual Studio Express 2013
    
    
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <map>
    
    
    using namespace std;
    const int ARRAY_SIZE_DEFAULT = 32;
    
    class vectorOfInt {
    
        public:
            vectorOfInt();            //A no-argument constructor that allocates a 32-element vector
            vectorOfInt(int size);    //A constructor that takes an initial size as the argument
            ~vectorOfInt();            //Destructor
            
            //vectorOfInt& operator= (const vectorOfInt& vec);
            vectorOfInt(const vectorOfInt& vec);
            
            int size();                // return length
            void pushback(int val);  // A method pushback that adds an element to the end of the array, resizing if necessary
            void pushfront(int val);  // A method pushfront that adds an element to the beginning of the array
            int getVal(int index);  //A method get, taking an index and returning the value at that index
            void setVal(int index, int val);  //A method set, that takes an index and a value, and sets the value at that index
            int& operator[](int index);        //assignment operator
    
        private:    //variables
    
            int *pa;                //Points to the array
            int length;                //The Number of Elements in an array
            int nextIndex;            //The Next Highest Index Value.  Head value
    
    };
    
    //Copy Constructor
    vectorOfInt::vectorOfInt(const vectorOfInt& vec){
    
        int *panew;
        
        int len = vec.length;
        panew = new int[len];
        memcpy(panew, vec.pa, len);
        
    }
    
    //Constructor with User Input on size
    vectorOfInt::vectorOfInt(int size){
        //!!!Check to see if size is appropriate value, i.e., > 0
        pa = new int[size];   //new provides memory to user-defined number of ints, which pa points to.
        //initialize array to zero.
        for (int x = 0; x < size; ++x)  { pa[x] = 0; }
        length = size;    //default array size
        nextIndex = 0;                    //nextIndex points to the first address
    }//end 
    
    
    
    int main(){
    
        int lena, lenb, lenc, i;
    
        vectorOfInt a(8);
        lena = a.size();
    
        for (i = 0; i < lena; ++i){
            a.setVal(i, i+10);
        }
    
        vectorOfInt c(a); //copy constructor test    
        lenc = c.size();
    }
    The size of c is 0. Values of a were not copied to c, although they appear to do so within the copy constructor routine.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You don't set any of the member variables to anything; at some point you should assign values to pa, length, and nextIndex in your constructor. (You know, like you did in your other constructor.)

  3. #3
    Registered User
    Join Date
    Dec 2013
    Location
    Oregon
    Posts
    7
    Yes, I changed my copy constructor accordingly:

    Code:
    //Copy Constructor
    vectorOfInt::vectorOfInt(const vectorOfInt& vec){
    
        
        length = vec.length;
        //panew = new int[length];
        pa = new int[length];
        //memcpy(panew, vec.pa, length);
        memcpy(pa, vec.pa, length);
        nextIndex = vec.nextIndex;
        
    }
    and this worked to some extent, but not without errors.It copies the first few elements correctly but then gives me garbage.

    Newbie trying to figure out copy constructors-cppoutput-jpg
    Attached Images Attached Images Newbie trying to figure out copy constructors-cppoutput-jpg 
    Last edited by froboz; 12-13-2013 at 06:33 PM.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Why not copy the whole array?
    Code:
    memcpy(pa, vec.pa, length*sizeof(int));
    (The last item is the number of bytes, not the number of items, because memcpy has no idea what objects these things are.)

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by froboz View Post
    Yes, I changed my copy constructor accordingly:

    Code:
    //Copy Constructor
    vectorOfInt::vectorOfInt(const vectorOfInt& vec){
    
        
        length = vec.length;
        //panew = new int[length];
        pa = new int[length];
        //memcpy(panew, vec.pa, length);
        memcpy(pa, vec.pa, length);
        nextIndex = vec.nextIndex;
        
    }
    and this worked to some extent, but not without errors.It copies the first few elements correctly but then gives me garbage.
    As tabstop pointed out, you weren't copying enough with memcpy().

    I also wouldn't do it that way either. Instead, it is better to initialisers
    Code:
    vectorOfInt::vectorOfInt(const vectorOfInt& vec) : pa(new int[vec.length]), length(pa.length), nextIndex(pa.nextIndex)
    {
        memcpy(pa, vec.pa, length*sizeof(*pa));
    }
    Not such a big deal with simple examples like this, but for classes that contain instances other classes the difference is significant - an initialiser list constructs a copy of the relevant members directly, rather than unnecessarily default-constructing them and then altering their value.

    It is also easier to achieve exception safety with initialisers.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You should be using std::copy rather than memcpy, which would have meant that this bug would not have occurred in the first place.

    Why do you #include <map>?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    Registered User
    Join Date
    Dec 2013
    Location
    Oregon
    Posts
    7
    Thanks Tabstop, grumpy and iMalc. I copied this file over from another which did use <map> and simply forgot to delete the reference.

  8. #8
    Registered User
    Join Date
    Jul 2013
    Location
    Germany
    Posts
    499
    You should only use memcpy() it for raw data, if you use it on objects you might get nasty surprises. For objects you should use std::copy().

    Use <algorithm>

    http://www.cplusplus.com/reference/algorithm/copy/
    Last edited by jocdrew21; 12-16-2013 at 02:53 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with copy constructors
    By arya6000 in forum C++ Programming
    Replies: 2
    Last Post: 11-19-2008, 01:34 AM
  2. Help with copy constructors
    By nessie in forum C++ Programming
    Replies: 4
    Last Post: 04-24-2005, 07:50 AM
  3. Copy Constructors... *Newbie Alert!*
    By PLC in forum C++ Programming
    Replies: 9
    Last Post: 01-14-2004, 09:48 AM
  4. Copy Constructors
    By ygfperson in forum C++ Programming
    Replies: 8
    Last Post: 05-13-2003, 12:06 AM
  5. Copy constructors and private constructors
    By Eibro in forum C++ Programming
    Replies: 5
    Last Post: 11-24-2002, 10:16 AM