0
votes

Method:

vector <Expression*> Addition :: getAdditiveTerms() {
vector <Expression*> terms;
if((obj1->getType() == "Addition" || obj1->getType() == "Subtraction") && (obj2->getType() == "Addition" || obj2->getType() == "Subtraction")) {
    if(obj1->getLeftSide()->getType() == "Integer") {
        Expression* LL = obj1->getLeftSide();
        terms.push_back(LL);
        delete obj1->getLeftSide();
    }
    if(obj1->getRightSide()->getType() == "Integer") {
        Expression* LR = obj1->getRightSide();
        terms.push_back(LR);
        delete obj1->getRightSide();
    }
    if(obj2->getLeftSide()->getType() == "Integer") {
        Expression* RL = obj2->getLeftSide();
        terms.push_back(RL);
        delete obj2->getLeftSide();
    }
    if(obj2->getRightSide()->getType() == "Integer") {
        Expression* RR = obj2->getRightSide();
        terms.push_back(RR);
        delete obj2->getRightSide();
    }
}
return terms;
}

When I create a an object and try to access this method, I get the following error:

ExpressionCalculator(19982,0x7fff8b43e380) malloc: * error for object 0x7ffedfe729a8: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug

Main where object is being created:

int main() {
    Integer integ1("1");
    Integer integ2("-2");
    Integer* integer1 = &integ1;
    Integer* integer2 = &integ2;
    Addition add1(integer1, integer2);
    Integer integ3("6");
    Integer integ4("-9");
    Integer* integer3 = &integ3;
    Integer* integer4 = &integ4;
    Addition add2(integer3, integer4);
    Addition* addit1 = &add1;
    Addition* addit2 = &add2;

    Addition add3(addit1, addit2);

    vector <Expression*> addTerms = add3.getAdditiveTerms();

    for(int i = 0; i < addTerms.size(); i++)
        cout << addTerms[i]->getValue() << endl;

}

Now, I realize the way I'm getting these pointers into the constructor looks a little odd, I had to make pointers in order to test it in the fashion that the parameters will be passed throughout the program. Any ideas why I'm getting this error? I'm sure it has to do with an ill-defined pointer. Thanks!

1

1 Answers

0
votes

The error you get is pretty clear, you're trying to delete a pointer that references an object for which you didn't allocate memory (tipically using the new operator).

The code of your main and getAdditiveTerms functions feels clumsy regarding pointers. You are mixing pointer and non-pointer variables. If you need pointers in your Addition constructor, why don't you pass directly a pointer:

Integer* integer1 = new Integer("1");
Integer* integer2 = new Integer("-2");
Addition add1(integer1, integer2);

Then, you can delete the Integer pointers either in the Addition desctructor (which seems to be the best choice here) or whenever you don't need them anymore.

Regarding getAdditiveTerms, why are you deleting objects here? It feels strange to delete pointers in such getter method. I think you can remove those delete statements.

To sum up:

// Remove delete statements
vector <Expression*> Addition :: getAdditiveTerms() {
vector <Expression*> terms;
if((obj1->getType() == "Addition" || obj1->getType() == "Subtraction") && (obj2->getType() == "Addition" || obj2->getType() == "Subtraction")) {
    if(obj1->getLeftSide()->getType() == "Integer") {
        Expression* LL = obj1->getLeftSide();
        terms.push_back(LL);
    }
    if(obj1->getRightSide()->getType() == "Integer") {
        Expression* LR = obj1->getRightSide();
        terms.push_back(LR);
    }
    if(obj2->getLeftSide()->getType() == "Integer") {
        Expression* RL = obj2->getLeftSide();
        terms.push_back(RL);
    }
    if(obj2->getRightSide()->getType() == "Integer") {
        Expression* RR = obj2->getRightSide();
        terms.push_back(RR);
    }
}
return terms;
}

// Use pointers
int main() {
    Integer* integer1 = new Integer("1");
    Integer* integer2 = new Integer("-2");
    Addition* add1 = new Addition(integer1, integer2);
    Integer* integer3 = new Integer("6");
    Integer* integer4 = new Integer("-9");
    Addition* add2 = new Addition(integer3, integer4);
    Addition* add3 = new Addition(addit1, addit2);

    vector <Expression*> addTerms = add3->getAdditiveTerms();

    for(int i = 0; i < addTerms.size(); i++)
        cout << addTerms[i]->getValue() << endl;

    delete add3;
    delete add2;
    delete add1;
    delete integer4;
    delete integer3;
    delete integer2;
    delete integer1;
}

Edit using Addition destructor

If you aim to use the Addition destructor:

// In the Addition class, you need this
Addition::~Addition() {
    delete m_leftSide; // Customize with the proper attribute
    delete m_rightSide; // Customize with the proper attribute
}

// You don't need to delete all your pointers in the main now
int main() {
    Integer* integer1 = new Integer("1");
    Integer* integer2 = new Integer("-2");
    Addition* add1 = new Addition(integer1, integer2);
    Integer* integer3 = new Integer("6");
    Integer* integer4 = new Integer("-9");
    Addition* add2 = new Addition(integer3, integer4);
    Addition* add3 = new Addition(addit1, addit2);

    vector <Expression*> addTerms = add3->getAdditiveTerms();

    for(int i = 0; i < addTerms.size(); i++)
        cout << addTerms[i]->getValue() << endl;

    delete add3; // Will recusively delete all the pointers
}