0
votes

I have a struct defined as follows

struct VariableList
{
    void Add(simple_instr* instr)
    {
        //PrintOpcode(instr);
        switch(instr->opcode)
            {
                case STR_OP:
                case MCPY_OP:
                    Add(instr->u.base.src1);
                    Add(instr->u.base.src2);
                    break;  

                case LDC_OP: 
                    Add(instr->u.ldc.dst);
                    break;  

                case BTRUE_OP:
                case BFALSE_OP: 
                    Add(instr->u.bj.src);
                    break;              

                case CALL_OP:
                    if (instr->u.call.dst != NO_REGISTER)
                    {
                        Add(instr->u.call.dst);
                    }

                    Add(instr->u.call.proc);

                    for (int i = 0; i < instr->u.call.nargs; i++)
                    {
                        Add(instr->u.call.args[i]);
                    }

                    break;

                case MBR_OP:                    
                    Add(instr->u.mbr.src);
                    break;          

                case RET_OP:
                    if (instr->u.base.src1 != NO_REGISTER)
                        Add(instr->u.base.src1);
                    break;              

                case CVT_OP:
                case CPY_OP:
                case NEG_OP:
                case NOT_OP: 
                case LOAD_OP: 
                    Add(instr->u.base.dst);
                    Add(instr->u.base.src1);
                    break;

                case LABEL_OP:
                case JMP_OP:
                    break;                      

                default:
                    Add(instr->u.base.dst);
                    Add(instr->u.base.src1);
                    Add(instr->u.base.src2);
                    break;

            }
    }

    void Add(Variable var)
    {
        variableList.push_back(var);
    }

    void RemoveDuplicates()
    {
        if (variableList.size() > 0)
        {
            variableList.erase(unique(variableList.begin(), variableList.end()), variableList.end());
            currentID = variableList.size();
        }
    }

    VariableList()
    {
        currentID = 0;
        dynamicallyCreated = false;
    }

    VariableList(VariableList& varList, bool setLiveness = false, bool LiveVal = false)
    {
        currentID = 0;
        for (int i = 0; i < varList.size(); i++)
        {
            Variable* var = new Variable(varList[i]);
            if (setLiveness)
            {
                var->isLive = LiveVal;
            }

            variableList.push_back(*var);
        }

        dynamicallyCreated = variableList.size() > 0;
    }

    Variable& operator[] (int i)
    {
        return variableList[i];
    }

    int size()
    {
        return variableList.size();
    }

    vector<Variable>::iterator begin()
    {
        return variableList.begin();
    }

    vector<Variable>::iterator end()
    {
        return variableList.end();
    }

    bool CompareLiveness(VariableList &var)
    {
        if(variableList.size() != var.size())
        {
            return false;
        }

        for (int i = 0; i < variableList.size(); i++)
        {
            if(variableList[i].isLive != var[i].isLive)
                return false;
        }
        return true;
    }

    ~VariableList()
    {
        if(dynamicallyCreated)
        {
            for (vector<Variable>::iterator it = variableList.begin(); it < variableList.end(); ++it)
            {
                //delete (&it);
            }
        }
    }

    protected:
        int currentID;
        vector<Variable> variableList;
        bool dynamicallyCreated;
        void Add(simple_reg* reg, bool checkForDuplicates = false)
        {   
            if (reg == null)
            {
                cout << "null detected" << endl;
                return;
            }

            if (reg->kind == PSEUDO_REG)
            {                       
                if (!checkForDuplicates || (checkForDuplicates && find(variableList.begin(), variableList.end(), reg->num) != variableList.end()))
                {
                    cout << "Adding... Reg  " << reg->num << endl;
                    Variable* var = new Variable(reg->num, currentID);              
                    variableList.push_back(*var);
                    currentID++;
                }
            }
        }
};

I'd like to be able to do a statement like this

VariableList varsIn(Variables, true, false);

that will create a deep copy and allow me to change a few properties. As you can see in my struct, I'm currently attempting to do this using

VariableList(VariableList& varList, bool setLiveness = false, bool LiveVal = false)
{
    currentID = 0;
    for (int i = 0; i < varList.size(); i++)
    {
        Variable* var = new Variable(varList[i]);
        if (setLiveness)
        {
            var->isLive = LiveVal;
        }

        variableList.push_back(*var);
     }

     dynamicallyCreated = variableList.size() > 0;
}

I don't think this is the right way to do it though. What's the proper way to do this sort of copying? Is there a way to do it without using new? For reference, the Variable struct is as follows

struct Variable
{
    int id;
    int num;
    bool isLive;
    simple_op opcode;

    Variable()
    {
        id = 0;
    num = 0;
    opcode = NOP_OP;
    vClass = Basic;
    isLive = false;
    }

    Variable(int _num, int _id = 0, simple_op _op = NOP_OP)
    {
        id = _id;
    num = _num;
    opcode = _op;
    vClass = Basic;
    isLive = false;
    }

    VariableClass GetClass()
    {
        return vClass;
    }

    bool operator==(const Variable &var) const 
    {
        return num == var.num;
    }

    bool operator==(const int &x) const
    {
    return x == num;
    }

    protected:
        VariableClass vClass;
};

VariableClass and simple_op are enums

Thanks in advance

1

1 Answers

2
votes

Your code is not only doing dynamic allocation unnecessarily, it's also leaking Variable instances everywhere. Just use an automatic variable, push_back will make a copy:

VariableList(VariableList& varList, bool setLiveness = false, bool LiveVal = false)
{
    currentID = 0;
    for (int i = 0; i < varList.size(); i++)
    {
        Variable var(varList[i]);
        if (setLiveness)
        {
            var.isLive = LiveVal;
        }

        variableList.push_back(var);
     }
}

And take out the destructor, you can't delete the elements owned by the vector. If they pointed somewhere, sure, but you're not storing pointers.

Also, here's an even better way:

VariableList(VariableList& other, bool setLiveness = false, bool LiveVal = false)
    : currentID(0)
    , variableList(other.variableList)
{
    if (setLiveness) {
        for( int i = 0; i < size(); i++ )
            variableList[i].isLive = LiveVal;
    }
}