У меня странное поведение с вектором в C ++. Я надеялся, что кто-нибудь мне поможет.У меня есть такой вектор:
vector<Instruction*> allInstrs;
структура для инструкции выглядит следующим образом:
struct Instruction : simple_instr
{
InstrType type;
Instruction(const simple_instr& simple) : simple_instr(simple)
{
type = Simple;
loopHeader = false;
loopTail = false;
}
int Id;
bool loopHeader;
bool loopTail;
};
проблема у меня заключается в следующем:
мне нужновыполнять итерацию по каждой инструкции, извлекать определенные поля и использовать их для анализа команд в векторе.Чтобы сделать это, я в основном делал
VariableList Variables;
void GenerateVariableList()
{
for (int i = 0; i < allInstrs.size(); i++)
{
Variables.Add(allInstrs[i]);
}
Variables.RemoveDuplicates();
}
Список переменных определяется как
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:
cout << "CALL OP" <<endl;
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;
}
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);
}
}
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();
}
protected:
int currentID;
vector<Variable> variableList;
void Add(simple_reg* reg, bool checkForDuplicates = false)
{ cout << "Register Check" <<endl;
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(reg->num, currentID);
variableList.push_back(var);
currentID++;
}
}
}
};
Когда я делаю это, каждая инструкция переходит к оператору по умолчанию, даже если я знаюна самом деле некоторые инструкции не должны.Если я изменю GenerateVariableList на
void GenerateVariableList()
{
for (int i = 0; i < allInstrs.size(); i++)
{
PrintOpcode(allInstrs[i]);
Variables.Add(allInstrs[i]);
}
Variables.RemoveDuplicates();
}
, так что теперь есть второй PrintOpCode в дополнение к тому, что в Variables.Add, программа будет работать правильно.Я не могу понять, почему добавление второго PrintOpcode заставляет его работать правильно.Весь код операции печати - это функция с оператором switch, которая просто печатает конкретную строку в зависимости от значения одного из полей simple_instr.
Переменные VariableList содержатся внутри отдельной структуры CFG
Если вам нужна дополнительная информация / код, я могу ее предоставить.Если ответ очевиден, я прошу прощения, я не очень часто программирую на C ++
РЕДАКТИРОВАТЬ:
Один из оставшихся ответов, удаленный сейчас, принес мне исправление.
Раньше я делал
static vector<Instruction*> ConvertLinkedListToVector(simple_instr* instructionList)
{
vector<Instruction*> convertedInstructions;
int count = 0;
for (simple_instr* current = instructionList; current; count++, current = current->next)
{
//Instruction* inst = new Instruction(*current);
Instruction inst = Instruction(*current);
inst.Id = count;
convertedInstructions.push_back(&inst);
}
return convertedInstructions;
}
, чтобы сделать вектор, но после прочтения этого ответа я снова изменил его на использование "new", и теперь он работает правильно.Спасибо за помощь, извините за тупой вопрос хех