Всем привет!
Помогите разрулить проблему, уже второй час бьюсь!
Быдлокожу алгоритм парсинга формулы. Парсинг работает нормально. Теперь пишу упрощение - раскрытие скобок, функция Simplify.
Весь исходник: http://pastebin.com/C9he4AEK Запускаю так: $ g++ -std=c++11 semantic.cpp -o semantic && ./semantic
При запуске выдает Segmentation fault на удалении элемента из вектора operands.
Еще интересно, что, если убрать вставку (operands.insert(...)) то Segmentation fault нет. Сама вставка проходит корректно и итератор i указывает куда нужно.
Что не так???
Сам код:
void CSum::Simplify()
{
FUNC("");
vector<CFunction*>::iterator i,j,prev;
CSum *tmp;
LOG("We are in '"<<PrintTree()<<"'");
for (i=operands.begin();i!=operands.end();i++){
if ((*i)==nullptr)
throw "Error in SC: empty operands in Sum";
LOG("Simplifying operand type:"<<(*i)->PrintType());
(*i)->Simplify();
if ((*i)->type==sum){ // Opening Brackets
LOG("Opening brackets of "<< PrintTree() <<"...");
j=i;
j++;
operands.insert(j,((CBinaryFunction*)(*i))->operands.begin(),((CBinaryFunction*)(*i))->operands.end());
LOG("...deleting old one "<<(*i)->PrintTree()<<", type:"<<(*i)->PrintType()<<", from "<<PrintTree()<<"...");
// tmp=(CSum*)(*i);
// delete[] tmp;
*i=nullptr;
operands.erase(i);
LOG("...done");
i=operands.begin(); // TODO: this is incorrect. We need to continue just from previous element. Fix this!
}
};
RETURN("");
};
Структура классов:
class CFunction{
public:
enum TFunctionType {
var,
sum,
mul
};
const TFunctionType type;
CFunction(const TFunctionType t):type(t){};
virtual TFormula Get()=0;
virtual uint GetOperandsNum()=0;
virtual bool IsValid()=0;
string PrintType(){ // For debugging needs
switch (type) {
case var: return "var";
case sum: return "sum";
case mul: return "mul";
}
return "unknown";
}
virtual string PrintTree()=0; // For debugging needs; prints even invalid structures
virtual void Simplify()=0; // Expand brackets etc
};
//////////////////////////
class CVariable: public CFunction{
public:
TValue value;
bool inverted;
CVariable():CFunction(var),value(""),inverted(false){};
CVariable(TValue v):CFunction(var),value(v),inverted(false){};
CVariable(TValue v,bool i):CFunction(var),value(v),inverted(i){};
virtual TFormula Get();
virtual uint GetOperandsNum(){return 1;};
virtual bool IsValid(){return !value.empty();};
virtual string PrintTree(){ if (value.empty()) return "''"; else return value;}; // For debugging needs; TODO: should print invalid structures ; TODO: inversion
virtual void Simplify(){return;}; // Nothing to simplify in a simple variable
};
//////////////////////////
class CBinaryFunction:public CFunction{ // Actually - function with many arguments
public:
vector<CFunction*> operands;
CBinaryFunction(const TFunctionType t):CFunction(t){};
CBinaryFunction(const TFunctionType t,CFunction *o1):CFunction(t){
AddOperand(o1);
};
CBinaryFunction(const TFunctionType t,CFunction *o1,CFunction *o2):CFunction(t){
AddOperand(o1);
AddOperand(o2);
};
~CBinaryFunction(){
for (auto i:operands)
if (i!=nullptr)
delete[] i;
operands.erase(operands.begin(),operands.end());
};
virtual uint AddOperand(CFunction *f){operands.push_back(f);};
virtual uint GetOperandsNum(){return operands.size();};
virtual bool IsValid();
};
//////////////////////////
class CSum: public CBinaryFunction{
public:
CSum():CBinaryFunction(sum){};
CSum(CFunction *o1):CBinaryFunction(sum,o1){};
CSum(CFunction *o1,CFunction *o2):CBinaryFunction(sum,o1,o2){};
~CSum();
virtual TFormula Get();
virtual string PrintTree(); // For debugging needs; prints even invalid structures
virtual void Simplify();
};
//////////////////////////
class CMul: public CBinaryFunction{
public:
CMul():CBinaryFunction(mul){};
CMul(CFunction *o1):CBinaryFunction(mul,o1){};
CMul(CFunction *o1,CFunction *o2):CBinaryFunction(mul,o1,o2){};
~CMul();
virtual TFormula Get();
virtual string PrintTree(); // For debugging needs; prints even invalid structures
virtual void Simplify();
};
Лог:
semantic.cpp:261: >>> Simplify()
semantic.cpp:265: We are in '(a+(b+c))'
semantic.cpp:270: Simplifying operand type:var
semantic.cpp:270: Simplifying operand type:sum
semantic.cpp:261: >>> Simplify()
semantic.cpp:265: We are in '(b+c)'
semantic.cpp:270: Simplifying operand type:var
semantic.cpp:270: Simplifying operand type:var
semantic.cpp:287: <<< Simplify() returns
semantic.cpp:273: Opening brackets of (a+(b+c))...
semantic.cpp:277: ...deleting old one (b+c), type:sum, from (a+(b+c)+b+c)...
Segmentation fault