Search code examples
c++copy-constructorassignment-operatordelete-operator

Deleting Private Array in Copy Constructor and Assignment operator


I'm trying to implement a container that allocated memory to the heap, but it seems as though my base constructor and my argument constructor don't like each other. Below, I've posted the code without anything commented out. As it stands, it crashes.

#include <iostream>
using namespace std;

class foo
{
public:
    foo() {size=1; vals = new double[1]; vals[0]=0;}
    ~foo() {delete[] vals;}

    foo(const foo& other)
    {
        size=other.getsize();
        delete[] vals;
        vals = new double[size];
        for(long unsigned i=0; i<size; i++)
            vals[i]=other[i];
    }

    foo& operator=(const foo& other)
    {
        size=other.getsize();
        delete[] vals;
        vals = new double[size];
        for(long unsigned i=0; i<size; i++)
            vals[i]=other[i];
        return *this;
    }

    foo(double* invals, long unsigned insize)
    {
        size=insize;
        delete[] vals;
        vals = new double[size];
        for(long unsigned i=0; i<size; i++)
            vals[i]=invals[i];
    }

    double operator[](long unsigned i) const {return vals[i];}

    long unsigned getsize() const {return size;}
private:
    double* vals;
    long unsigned size;
};


int main()
{
    double bar[3] = {5,2,8};
    foo B(bar, 3);

    cout<< B[0]<< " "<< B[1]<< " "<< B[2]<<endl;    //couts fine

    foo A;    //crashes here

    return 0;
}

However, when I change main to be:

int main()
{
    double bar[3] = {5,2,8};
    foo B(bar, 3);

    cout<< B[0]<< " "<< B[1]<< " "<< B[2]<<endl;    //couts fine

    foo A();    //works now

    return 0;
}

It runs fine. But then I can't assign A = B because it thinks foo is a function or something.


Solution

  • I assume you have some really compelling reason not to use std::vector<double> here...

    But anyway... in your copy constructor, you don't want to delete[] vals.

    foo(const foo& other)
    {
        size=other.getsize();
        vals = new double[size];
        for(long unsigned i=0; i<size; i++)
            vals[i]=other[i];
    }
    

    When the copy constructor is called, your object hasn't been initialized yet, so vals* doesn't even point to anything valid. Therefore, deleting it invokes undefined behavior (and your program crashes.) You only need to delete[] vals in your assignment operator.

    Also, when you declare the Foo variable A, you don't want those parentheses after the variable name. Just say:

    foo A;
    

    When you place those parenthesis after the variable name, you're actually writing a function declaration using syntax inherited from C, and A becomes a function pointer type.