Set values in an array within an object - c++

I've got an issue with an Object array in an object:
I have a class with an object array:
class element
{
public:
element() {};
LinePiece* arrayLP;
and I have a class thats in the array:
class LinePiece
{
public:
LinePiece() {};
AnsiString Type;
int ElementNr;
int Status;
int X, Y;
so within the Element object I have a LinePiece array. The odd thing is, when I fill in ElementArray[1].LPArray[0]; it gets overwritten by the next object (ElementArray[2].LPArray[0];
I fill it with the following code:
String FileBuffer;
String Regel;
String Code;
element* GetElementInfo()
{
//alle onderdelen van een Elementobject
String OrderNumber; //ON
String OrderBrand; //MO
String ElementNumber; //SN
String ElementMarking; //RS
String ReinforcementPattern; //OW
String CalculationNumber; //CN
String ElementLength; //LE
String ElementWidth; //WD
String ElementBeginX; //BP
String ConcreteThickness; //TH
String Isulation; //IH
String Weight; //NW
element *ElementArray = new element[100];
LinePiece *LPArray = new LinePiece[100];
bool firstElement = true;
int Index =0;
int LPIndex = 0;
for(int i = 1; i <= FileBuffer.Length(); i++)
{
if(FileBuffer[i] != 0)
{
if(FileBuffer[i] != IntToStr('\r')) //controleren of je op einde regel zit, zoniet vul de string "regel" aan
{
if(FileBuffer[i] != IntToStr('\r') && FileBuffer[i] != IntToStr('\n'))
{
Regel = Regel + FileBuffer[i];
}
}
else //kijken wat er op de regel staat
{
Code = Regel.SubString(0,2);
if(Code == "ON") //Ordernummer
{
OrderNumber = Regel.SubString(4, (Regel.Length() -3));
Regel = "";
}
if(Code =="MO") //Ordermerk
{
OrderBrand = Regel.SubString(4, (Regel.Length() -3));
Regel = "";
}
if(Code =="SN") //Element nummer
{
ElementNumber = Regel.SubString(4, (Regel.Length()-3));
Regel = "";
}
if(Code =="RS") //Element marking
{
ElementMarking = Regel.SubString(4, (Regel.Length()-3));
Regel = "";
}
if(Code =="CN") //Calculatienummer
{
CalculationNumber = Regel.SubString(4, (Regel.Length()-3));
Regel = "";
}
if(Code == "LE") //Element lengte
{
ElementLength = Regel.SubString(4,(Regel.Length()-3));
Regel = "";
}
if(Code == "WD") //element breedte
{
ElementWidth = Regel.SubString(4,(Regel.Length()-3));
Regel = "";
}
if(Code == "BP") //beginpunt X
{
ElementBeginX = Regel.SubString(4, (Regel.Length()-3));
Regel = "";
}
if (Code == "OW") //Wapeningspatroon
{
ReinforcementPattern = Regel.SubString(4, (Regel.Length()-3));
Regel = "";
}
if(Code == "TH") //Beton dikte
{
ConcreteThickness = Regel.SubString(4,(Regel.Length()-3));
Regel = "";
}
if(Code == "IH") //isolatie dikte
{
Isulation = Regel.SubString(4,(Regel.Length()-3));
Regel = "";
}
if(Code == "NW") //Gewicht
{
Weight = Regel.SubString(4, (Regel.Length()-3));
Regel = "";
}
if(Code == "CO") //Contour
{
String geheleRegel = Regel.SubString(4, (Regel.Length() -3));
int EleNr = 0;
int Status = 0;
//geheleRegel doormidden hakken voor x en y waardes.
String X = geheleRegel.SubString(0, (geheleRegel.Length() /2));
String Y = geheleRegel.SubString(geheleRegel.Length()/2 +1, geheleRegel.Length());
LinePiece lpObject(Code, EleNr, Status, StrToInt(X), StrToInt(Y));
LPArray[LPIndex] = lpObject;
LPIndex++;
Regel = "";
}
if(Code == "*" && firstElement == false) //Nieuw element
{
if(OrderNumber == "")
{
OrderNumber =="-";
}
if(OrderBrand == "")
{
OrderBrand = "-";
}
if(ElementNumber == "")
{
ElementNumber = "-";
}
if(ElementMarking == "")
{
ElementMarking = "-";
}
if (ReinforcementPattern == "")
{
ReinforcementPattern = "-";
}
if (CalculationNumber == "")
{
CalculationNumber = "-";
}
if(ElementLength == "")
{
ElementLength = 0;
}
if(ElementWidth == "")
{
ElementWidth = 0;
}
if(ElementBeginX == "")
{
ElementBeginX = 0;
}
if(ConcreteThickness == "")
{
ConcreteThickness = 0;
}
if(Isulation == "")
{
Isulation = 0;
}
if(Weight == "")
{
Weight = 0;
}
element ElementObject(OrderNumber, OrderBrand, ElementNumber, ElementMarking,
ReinforcementPattern, CalculationNumber, StrToInt(ElementLength), StrToInt(ElementWidth),
StrToInt(ElementBeginX), StrToInt(ConcreteThickness),StrToInt(Isulation),
Weight, LPArray);
ElementArray[Index] = ElementObject;
LPIndex = 0; /resetting LPIndex
Index++;
}
else
{
Regel="";
}
if (Code == "*")
{
firstElement = false;
}
}
}
}
return ElementArray;
}
So for some reason, it doesn't make 'X' different LPArrays, but overwrites all the LParrays with the last one. How can I fix this?

Your initialization code should looks like:
element *ElementArray = new element[100];
for ( int n = 0; n < 100; ++n )
ElementArray[n].arrayLP = new LinePiece[100];
so the behaviour you describe might be due to undefined bahaviour
you dont seem to delete your allocated array anywhere - that will cause memory leaks. Also if you want arrays and not vectors then you must obey rule of three (add copy constructor/operator and destructor).

Related

UndefinedBehaviorSanitizer: SEGV on unknown address

Hello, i was solving this -> kata on CodeWars.
I am using a VusialStudio 2019 to write code. When i start this project in VS no erros is presented to me. The program even works correctly for the first test case. But when i am testing it on problem's page it gives me an error:
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==1==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000429d24 bp 0x7ffc2f3f72b0 sp 0x7ffc2f3f7150 T1)
==1==The signal is caused by a READ memory access.
==1==Hint: address points to the zero page.
==1==WARNING: invalid path to external symbolizer!
==1==WARNING: Failed to use and restart external symbolizer!
#0 0x429d23 (/workspace/test+0x429d23)
#1 0x42ab1d (/workspace/test+0x42ab1d)
#2 0x429fa3 (/workspace/test+0x429fa3)
#3 0x42e2f2 (/workspace/test+0x42e2f2)
#4 0x42c9ce (/workspace/test+0x42c9ce)
#5 0x42c529 (/workspace/test+0x42c529)
#6 0x42c11b (/workspace/test+0x42c11b)
#7 0x431425 (/workspace/test+0x431425)
#8 0x42a08d (/workspace/test+0x42a08d)
#9 0x7f1b94116bf6 (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
#10 0x4053e9 (/workspace/test+0x4053e9)
UndefinedBehaviorSanitizer can not provide additional info.
==1==ABORTING
For a while i was turning on and off parts of program to determen where the problem is. I nereved it down to this line
Program::Status_enum Program::ExecuteComand(Comand_Class* ComandToExe)
{
else if (ComandToExe->name == "div")
{
this->Registers[ComandToExe->args[0]] /= GetValue(ComandToExe->args[1]); // error here
}
}
Leter i found out that error was showing up even if i chage line to
this->Registers.begin()->second = 3; // same error
this->Registers["a"] = 2; // same error
It looks to me that any change of value causes it to throw an error. But reaading for example was ok
int a = Registers["a"];
std::cout << a; // will print a right value
So this basikly all i was able to find out by my self. Here is structer of my code.
Basikly my goal is to write a Asmbler intorpritator
// All Comands saved as this class
class Comand_Class
{
public:
std::string name; // for example mov, div, etc.
std::vector<std::string> args; // data for the comand
Comand_Class(std::string Name, std::string arg1 = "", std::string arg2 = "")
{
//..
}
Comand_Class(std::string Name, std::vector<std::string> Args)
{
//..
}
};
// I use this class to store functions cod as a small program itself
class Function_Class
{
public:
std::vector<Comand_Class*> FunctionProgram;
};
// the main class
class Program
{
std::string MSG = "-1"; // for outout
std::unordered_map <std::string, int> Registers; // map in which the problem exsist
std::vector<Comand_Class*> ProgramLines; // Starting code
std::map<std::string,Function_Class*> CallList; // Name of Function and Her code to exe
// .exe is giving me back the status, after executing a Comand_Class line, this how i know what to do next.
enum Status_enum
{
END = 0,
CALL = 1,
JUMP = 2,
RET = 3,
CONTINUE = 10,
ERROR = -1,
};
public:
std::string Start()
{
exe(this -> ProgramLines );
return MSG;
}
int GetValue(std::string arg)
{
if ('a' <= arg[0] && arg[0] <= 'z')
{
//register
return this->Registers[arg];
}
else
{
int a = std::stoi(arg);
return a;
}
}
// not related to the problem,
void preprocesing(std::string program);
Status_enum ExecuteComand(Comand_Class* ComandToExe);
void exe(std::vector<Comand_Class*> ProgramLinesToExe);
~Program()
{
for (unsigned long i = 0; i < ProgramLines.size(); i++)
{
Comand_Class* del = ProgramLines.at(i);
delete del;
}
for (auto it = CallList.begin(); it != CallList.end(); it++)
{
for (unsigned long i = 0; i < it->second->FunctionProgram.size(); i++)
{
Comand_Class* del = it->second->FunctionProgram.at(i);
delete del;
}
}
// add CallList to clear
}
};
// this function is recurseve, Can this be a reson why it brakes?
void Program::exe(std::vector<Comand_Class*> ProgramLinesToExe)
{
Status_enum Status;
unsigned long int SubPC = 0; // Comand to exe
while (SubPC < ProgramLinesToExe.size())
{
Status = ExecuteComand(ProgramLinesToExe[SubPC]);
if (Status != CONTINUE)
{
if(Status == JUMP)
{
exe(CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram);
}
else if (Status == CALL)
{
auto test = CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram;
exe(CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram);
}
else if (Status == RET)
{
return;
}
else if (Status == END)
{
break;
}
else if (Status == ERROR)
{
std::cout << "Unknown comand! " << ProgramLinesToExe[SubPC]->name;
}
}
SubPC++;
}
}
// Untill this function called second time (recursively) all works good
Program::Status_enum Program::ExecuteComand(Comand_Class* ComandToExe)
{
if (ComandToExe->name == "mov")
{
this->Registers[ComandToExe->args[0]] = GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "inc")
{
this->Registers[ComandToExe->args[0]]++;
}
else if (ComandToExe->name == "dec")
{
this->Registers[ComandToExe->args[0]]--;
}
else if (ComandToExe->name == "add")
{
this->Registers[ComandToExe->args[0]] += GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "sub")
{
this->Registers[ComandToExe->args[0]] -= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "mil")
{
this->Registers[ComandToExe->args[0]] *= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "div")
{
//this->Registers[ComandToExe->args[0]] /= GetValue(ComandToExe->args[1]); error
}
else if (ComandToExe->name == "cmp")
{
int x = GetValue(ComandToExe->args[0]);
int y = GetValue(ComandToExe->args[1]);
this->CompareFlugs.Equal = (x == y);
this->CompareFlugs.Less = (x < y);
}
else if (ComandToExe->name == "jne") // if the values of the previous cmp command were not equal.
{
if (this->CompareFlugs.Equal == false)
{
return JUMP;
}
}
else if (ComandToExe->name == "je") // if the values of the previous cmp command were equal.
{
if (this->CompareFlugs.Equal == true)
{
return JUMP;
}
}
else if (ComandToExe->name == "jge") // if x was greater or equal than y in the previous cmp command.
{
if (this->CompareFlugs.Less == false)
{
return JUMP;
}
}
else if (ComandToExe->name == "jg") // f x was greater than y in the previous cmp command.
{
if ((this->CompareFlugs.Less == false) && (this->CompareFlugs.Equal == false))
{
return JUMP;
}
}
else if (ComandToExe->name == "jle") // if x was less or equal than y in the previous cmp command.
{
if ((this->CompareFlugs.Less == true) || (this->CompareFlugs.Equal == true))
{
return JUMP;
}
}
else if (ComandToExe->name == "jl") // if x was less than y in the previous cmp command.
{
if (this->CompareFlugs.Less == true)
{
return JUMP;
}
}
else if (ComandToExe->name == "call")
{
return CALL;
}
else if (ComandToExe->name == "ret")
{
return RET;
}
else if (ComandToExe->name == "end")
{
return END;
}
else if (ComandToExe->name == "msg")
{
MSG = "";
for (unsigned long int i = 0; i < ComandToExe->args.size(); i++)
{
if (ComandToExe->args[i][0] == '\'')
{
MSG += ComandToExe->args[i].substr(1);
}
else
{
MSG += std::to_string(GetValue(ComandToExe->args[i]));
}
}
}
else
{
return ERROR;
}
return CONTINUE;
}
That's all. Also i am new to stackoverflow, so if i did somting very bad, do not judge strictly.
And Here all the code, becase i cut parts i think was usless:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <map>
#include <unordered_map>
#include <regex>
class Comand_Class
{
public:
std::string name;
std::vector<std::string> args;
Comand_Class(std::string Name, std::string arg1 = "", std::string arg2 = "")
{
name = Name;
args.push_back(arg1);
if (!arg2.empty())
{
args.push_back(arg2);
}
}
Comand_Class(std::string Name, std::vector<std::string> Args)
{
name = Name;
args = Args;
}
};
class Function_Class
{
public:
//Comand_Class* ReturnControlTo = NULL;
std::vector<Comand_Class*> FunctionProgram;
};
class Program
{
//int PC = 0;
std::string MSG = "-1";
std::unordered_map <std::string, int> Registers;
std::vector<Comand_Class*> ProgramLines;
std::map<std::string,Function_Class*> CallList;
class CompareFlugs_Class
{
public:
bool Less = false;
bool Equal = false;
}CompareFlugs;
enum Status_enum
{
END = 0,
CALL = 1,
JUMP = 2,
RET = 3,
CONTINUE = 10,
ERROR = -1,
};
const std::string AllowedCommands = "mov inc dev add sub mul div cmp";
public:
std::string Start()
{
exe(this -> ProgramLines );
return MSG;
}
int GetValue(std::string arg)
{
if ('a' <= arg[0] && arg[0] <= 'z')
{
//register
return this->Registers[arg];
}
else
{
int a = std::stoi(arg);
return a;
}
}
void preprocesing(std::string program);
Status_enum ExecuteComand(Comand_Class* ComandToExe);
void exe(std::vector<Comand_Class*> ProgramLinesToExe);
~Program()
{
for (unsigned long i = 0; i < ProgramLines.size(); i++)
{
Comand_Class* del = ProgramLines.at(i);
delete del;
}
for (auto it = CallList.begin(); it != CallList.end(); it++)
{
for (unsigned long i = 0; i < it->second->FunctionProgram.size(); i++)
{
Comand_Class* del = it->second->FunctionProgram.at(i);
delete del;
}
}
// add CallList to clear
}
};
void Program::preprocesing(std::string program)
{
std::string read;
Comand_Class*NewProgramLine;
std::istringstream iss(program);
std::smatch matches;
std::regex Comand(";(.*)|call\\s(.*)|(end|ret)|msg(.*)[;]?|(\\w+):|(j\\w{1,2})\\s+(\\w+)|(\\w+)\\s+(\\w),?\\s?(\\d+|\\w)?");
bool WtireToFunction = false;
std::string ActiveLabel;
Function_Class* NewFunction = nullptr;// = new Function_Class;
while (!iss.eof())
{
std::getline(iss, read);
std::regex_search(read, matches, Comand);
/*
if (matches.size() != 0)
std::cout << "Comand is " << matches[0] << "\n";
*/
// parcing
std::string Coment = matches[1];
std::string CallLabel = matches[2];
std::string End = matches[3];
std::string Message = matches[4]; // may contain a comment in the end
std::string Label = matches[5];
std::string JumpComand = matches[6];
std::string JumpLabel = matches[7];
std::string ComandName = matches[8];
std::string arg1 = matches[9];
std::string arg2 = matches[10];
if ((!ComandName.empty()) && (AllowedCommands.find(ComandName) != std::string::npos))
{
//std::cout << "Comand is " << matches[0] << "\n";
std::cout << "Comand is " << ComandName << " " << arg1 << " " << arg2 << "\n";
NewProgramLine = new Comand_Class (ComandName,arg1,arg2);
//NewProgramLine->name = ComandName;
//NewProgramLine->args.push_back(arg1);
if (WtireToFunction == false)
{
this->ProgramLines.push_back(NewProgramLine);
}
else
{
NewFunction->FunctionProgram.push_back(NewProgramLine);
}
}
else if (!JumpComand.empty()) // && (AllowedJumpComands.find(JumpComand) != std::string::npos))
{
std::cout << "Comand is " << JumpComand << " " << JumpLabel << "\n";
NewProgramLine = new Comand_Class(JumpComand, JumpLabel);
}
else if (!CallLabel.empty()) // on call
{
NewProgramLine = new Comand_Class("call", CallLabel);
this->ProgramLines.push_back(NewProgramLine); // add Call to the ProgramLines
}
else if (!Label.empty()) // Generate New SubProgram
{
WtireToFunction = true;
ActiveLabel = Label;
NewFunction = new Function_Class;
this->CallList[ActiveLabel] = NewFunction;
}
else if (!Message.empty())
{
std::regex MessageParcing("('.*)'|,\\s(\\w)");
std::smatch matches;
std::sregex_iterator it(Message.begin(), Message.end(), MessageParcing), end;
std::vector<std::string> args;
while (it!= end)
{
matches = *it;
if (!matches[1].str().empty())
{
args.push_back(matches[1].str());
}
else if (!matches[2].str().empty())
{
args.push_back(matches[2].str());
}
else
{
std::cout << "Error: cannot format msg\n";
}
it++;
}
NewProgramLine = new Comand_Class("msg",args);
this->ProgramLines.push_back(NewProgramLine);
}
else if (!End.empty())
{
if (End == "end")
{
NewProgramLine = new Comand_Class("end");
this->ProgramLines.push_back(NewProgramLine); // add Call to the ProgramLines
}
if (End == "ret")
{
if (NewFunction == nullptr)
std::cout << "No Call Detected, but ret is found\n";
else
{
NewProgramLine = new Comand_Class("ret");
NewFunction->FunctionProgram.push_back(NewProgramLine);
}
}
}
}
}
Program::Status_enum Program::ExecuteComand(Comand_Class* ComandToExe)
{
if (ComandToExe->name == "mov")
{
this->Registers[ComandToExe->args[0]] = GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "inc")
{
this->Registers[ComandToExe->args[0]]++;
}
else if (ComandToExe->name == "dec")
{
this->Registers[ComandToExe->args[0]]--;
}
else if (ComandToExe->name == "add")
{
this->Registers[ComandToExe->args[0]] += GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "sub")
{
this->Registers[ComandToExe->args[0]] -= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "mil")
{
this->Registers[ComandToExe->args[0]] *= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "div")
{
int a = GetValue(ComandToExe->args[1]);
auto t = ComandToExe->args[0];
int b = 6 / 2;
this->MSG = "Hi";
this->Registers[t] = b;
this->Registers.begin()->second = 3;
//this->Registers[ComandToExe->args[0]] /= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "cmp")
{
int x = GetValue(ComandToExe->args[0]);
int y = GetValue(ComandToExe->args[1]);
this->CompareFlugs.Equal = (x == y);
this->CompareFlugs.Less = (x < y);
}
else if (ComandToExe->name == "jne") // if the values of the previous cmp command were not equal.
{
if (this->CompareFlugs.Equal == false)
{
return JUMP;
}
}
else if (ComandToExe->name == "je") // if the values of the previous cmp command were equal.
{
if (this->CompareFlugs.Equal == true)
{
return JUMP;
}
}
else if (ComandToExe->name == "jge") // if x was greater or equal than y in the previous cmp command.
{
if (this->CompareFlugs.Less == false)
{
return JUMP;
}
}
else if (ComandToExe->name == "jg") // f x was greater than y in the previous cmp command.
{
if ((this->CompareFlugs.Less == false) && (this->CompareFlugs.Equal == false))
{
return JUMP;
}
}
else if (ComandToExe->name == "jle") // if x was less or equal than y in the previous cmp command.
{
if ((this->CompareFlugs.Less == true) || (this->CompareFlugs.Equal == true))
{
return JUMP;
}
}
else if (ComandToExe->name == "jl") // if x was less than y in the previous cmp command.
{
if (this->CompareFlugs.Less == true)
{
return JUMP;
}
}
else if (ComandToExe->name == "call")
{
// написать адресс для возврата в структуру с функциями
return CALL;
}
else if (ComandToExe->name == "ret")
{
return RET;
}
else if (ComandToExe->name == "end")
{
return END;
}
else if (ComandToExe->name == "msg")
{
MSG = "";
for (unsigned long int i = 0; i < ComandToExe->args.size(); i++)
{
if (ComandToExe->args[i][0] == '\'')
{
MSG += ComandToExe->args[i].substr(1);
}
else
{
MSG += std::to_string(GetValue(ComandToExe->args[i]));
}
}
}
else
{
return ERROR;
}
return CONTINUE;
}
void Program::exe(std::vector<Comand_Class*> ProgramLinesToExe)
{
Status_enum Status;
unsigned long int SubPC = 0;
while (SubPC < ProgramLinesToExe.size())
{
Status = ExecuteComand(ProgramLinesToExe[SubPC]);
if (Status != CONTINUE)
{
if(Status == JUMP)
{
exe(CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram);
}
else if (Status == CALL)
{
auto test = CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram;
exe(CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram);
}
else if (Status == RET)
{
return;
}
else if (Status == END)
{
break;
}
else if (Status == ERROR)
{
std::cout << "Unknown comand! " << ProgramLinesToExe[SubPC]->name;
}
}
SubPC++;
}
}
std::string assembler_interpreter(std::string program)
{
Program Main;
Main.preprocesing(program);
return Main.Start();
}

How do you find the shortest path after the BFS algorithm?

while( !q.is_empty() )
{
loc = q.remove_from_front();
//cout << loc.row << " " << loc.col << endl;
if( (loc.row-1) >= 0) //north
{
loc2.row = loc.row-1;
loc2.col = loc.col;
if(maze[loc2.row][loc2.col] != '#' && visited[loc2.row][loc2.col] == false)
{
visited[loc2.row][loc2.col] = true;
q.add_to_back(loc2);
//loc = predecessor[loc.row][loc.col];
predecessor[loc2.row][loc2.col] = loc;
if(maze[loc2.row][loc2.col] == 'F')
{
result = 1;
maze[loc2.row][loc2.col] = '*';
break;
}
}
}
if(loc.col-1 >= 0) //West
{
loc2.row = loc.row;
loc2.col = loc.col-1;
if(maze[loc2.row][loc2.col] != '#' && visited[loc2.row][loc2.col] == false)
{
visited[loc2.row][loc2.col] = true;
q.add_to_back(loc2);
//loc = predecessor[loc.row][loc.col];
predecessor[loc2.row][loc2.col] = loc;
if(maze[loc2.row][loc2.col] == 'F')
{
result = 1;
maze[loc2.row][loc2.col] = '*';
break;
}
}
}
if(loc.row+1 < rows) //South
{
loc2.row = loc.row+1;
loc2.col = loc.col;
if(maze[loc2.row][loc2.col] != '#' && visited[loc2.row][loc2.col] == false)
{
visited[loc2.row][loc2.col] = true;
q.add_to_back(loc2);
// loc = predecessor[loc.row][loc.col];
predecessor[loc2.row][loc2.col] = loc;
if(maze[loc2.row][loc2.col] == 'F')
{
result = 1;
maze[loc2.row][loc2.col] = '*';
break;
}
}
}
if(loc.col+1 < cols) //East
{
loc2.row = loc.row;
loc2.col = loc.col+1;
if(maze[loc2.row][loc2.col] != '#' && visited[loc2.row][loc2.col] == false)
{
visited[loc2.row][loc2.col] = true;
q.add_to_back(loc2);
//loc = predecessor[loc.row][loc.col];
predecessor[loc2.row][loc2.col] = loc;
if(maze[loc2.row][loc2.col] == 'F')
{
result = 1;
maze[loc.row][loc.col] = '*';
break;
}
}
}
}
if(result == 1)
{
while()
{
//not sure...
}
}
This is my BFS algorithm and the main reason I asked this question is because the other questions similar to my own question tends to be done with vectors. I haven't learn vectors yet. What I am trying to do is to print the shortest path using '' characters to display it on valid elements. It should be in bounds, no walls visited (walls are '#' characters), and no element should be visited twice. I know that if I set my predecessor 2D array correctly, the shortest path should be displayed correctly. However, I am not sure if I did set it up correctly and how to actually fill in that path with '' characters...

Function pointer declared in struct for graph, assign same function

Basically i cant make work this logic simulator! I made an adjacency list that connects all the gates one to each other and then assign a value to them and AdjList that is the head should calculate the value using the function pointer. Problem is the only function it calls is And!(Xor Nand etc.. are never called)
The specific points are where pointer are initialized
struct AdjList
{
struct AdjListNode *head;
string GateName;
string OutputName;
bool result;
function <bool (vector <bool>)> ptrf;
};
and were they are assigned
if(i < Gate_IO.size() )
{
ptrPos = Gate_IO[i].find_first_of(' ');
switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
{
case strtoi("AND"):
{
VectorHeadPtr[i].ptrf = And;
break;
}
case strtoi("NAND"):
{
VectorHeadPtr[i].ptrf = Nand;
break;
}
case strtoi("OR"):
{
VectorHeadPtr[i].ptrf = Or;
break;
}
case strtoi("NOR"):
{
VectorHeadPtr[i].ptrf = Nor;
break;
}
case strtoi("XOR"):
{
VectorHeadPtr[i].ptrf = Xor;
break;
}
default:
break;
}
Then in function CalcGateValue() they are called to execute the program! it seems like they are recognised and assigned to the right value in VectorHeadPtr[i].ptrf i tried to cout in that point and it goes into that cycle but the only function called when i call CalcGateValue() is And! Am I missing something?
Here is the complete code:
#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int compare(string a, string b)
{
int n = count(a.begin(), a.end(), 'I');
int q = count(b.begin(), b.end(), 'I');
return n > q;
}
constexpr unsigned int strtoi(const char* str, int h = 0) //string to int for switch cycle
{
return !str[h] ? 5381:(strtoi(str, h+1)*33)^str[h];
}
bool Xor(vector<bool> inputs)
{ cout<<"Xor function called!"<<endl;
int counter = 0;
for (unsigned int i = 0;i < inputs.size(); i++)
{
if (inputs.at(i) == 1)
{
counter++;
}
}
if (counter % 2) //Xor gate gives output 1 if and odd number of 1 inputs is given
{
return 1;
}
else
{
return 0;
}
}
bool And(vector<bool> inputs) //static per richiamare la funzione dalla classe
{ cout<<"And function called!"<<endl;
for (int i = 0; i < (inputs.size()-1); i++)
{
if(inputs.at(i) == 0)
{
return 0;
}
}
return 1;
}
bool Nand(vector<bool> inputs)
{ cout<<"Nand function called!"<<endl;
return !And(inputs);
}
bool Or(vector<bool> inputs)
{cout<<"Or function called!"<<endl;
for (int i = 0; i < (inputs.size()-1); i++)
{
if (inputs.at(i) != inputs.at(i+1) )
{
return 1;
}
}
return inputs.at(0);//Any position it's ok because all nPoss are the same.
}
bool Nor(vector<bool> inputs)
{ cout<<"Nor function called!"<<endl;
return !Or(inputs);
}
/*
* Adjacency list node
*/
struct AdjListNode
{
int nPos;
bool gValue;
string name;
struct AdjListNode* next;
};
/*
* Adjacency list
*/
struct AdjList
{
struct AdjListNode *head;
string GateName;
string OutputName;
bool result;
function <bool (vector <bool>)> ptrf;
};
/**
* Class Graph
*/
class Graph
{
private:
int V;
int circInputs = 3;
int circOutputs = 2;
int circGates;
int PrimaryInputs = 0;
vector<string> ioPuts;
struct AdjList* VectorHeadPtr;
public:
Graph(vector<string> Gate_IO)
{
int ptrPos,cntr;
int cntrIO = 0;
int prevPrimaryInputs = 0;
bool flag_remove_duplicates = 0;
string GateToConnect;
circGates = Gate_IO.size();
V=Gate_IO.size() + circInputs + circOutputs; //n°gates+input+output letti dal file
sort (Gate_IO.begin(), Gate_IO.end(), compare);
for (cntr = 0; cntr < (Gate_IO.size()-1) && (PrimaryInputs == prevPrimaryInputs); cntr++)
{
PrimaryInputs = count (Gate_IO[cntr+1].begin(), Gate_IO[cntr+1].end(), 'I');
prevPrimaryInputs = count (Gate_IO[cntr].begin(), Gate_IO[cntr].end(), 'I');
}
PrimaryInputs = cntr; //Here starts first N
for (int i = 0;i<Gate_IO.size();i++)
VectorHeadPtr = new AdjList [V];
for (int i = 0; i < V; i++)
{
if(i < Gate_IO.size() )
{
ptrPos = Gate_IO[i].find_first_of(' ');
switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
{
case strtoi("AND"):
{
VectorHeadPtr[i].ptrf = And;
break;
}
case strtoi("NAND"):
{
VectorHeadPtr[i].ptrf = Nand;
break;
}
case strtoi("OR"):
{
VectorHeadPtr[i].ptrf = Or;
break;
}
case strtoi("NOR"):
{
VectorHeadPtr[i].ptrf = Nor;
break;
}
case strtoi("XOR"):
{
VectorHeadPtr[i].ptrf = Xor;
break;
}
default:
break;
}
VectorHeadPtr[i].head = NULL;
stringstream ss;
ss << Gate_IO[i];
for (string temp; ss >> temp;)
{
if ( (temp.at(0)=='I') || (temp.at(0)=='O') && (temp!="OR") )
{
ioPuts.push_back(temp);
}
else if (temp.at(0) == 'U')
{
VectorHeadPtr[i].GateName=temp;
}
}
ptrPos = Gate_IO[i].find_last_of(' ');
VectorHeadPtr[i].OutputName = Gate_IO[i].substr(ptrPos);
}
else
{
if (flag_remove_duplicates == 0)
{
sort (ioPuts.begin(), ioPuts.end() );
ioPuts.erase (unique (ioPuts.begin(), ioPuts.end() ), ioPuts.end() );
flag_remove_duplicates = 1;
}
VectorHeadPtr[i].head = NULL;
VectorHeadPtr[i].ptrf = NULL;
VectorHeadPtr[i].GateName = ioPuts[cntrIO];
cntrIO++;
}
}
for (int i = 0; i < Gate_IO.size(); i++)
{
for(int j = 0; j < 2; j++)
{
ptrPos = Gate_IO[i].find_first_of(' ')+1;
Gate_IO[i].erase (0,ptrPos);
}
ptrPos = Gate_IO[i].find_last_of(' ')+1;
Gate_IO[i].erase( ptrPos);
stringstream ss;
ss << Gate_IO[i];
ss >> GateToConnect;
for (string temp; ss >> temp;)
{
addEdge(GateToConnect,temp);
}
}
}
/**
* Creates new adjacency list node for addEdge function
*/
AdjListNode* newAdjListNode(int nPos, string Name)
{
AdjListNode* newNode = new AdjListNode;
newNode->nPos = nPos;
newNode->name = Name;
newNode->next = NULL;
return newNode;
}
/**
* Add edge to graph
*/
void addEdge(string source, string destination)
{
int from, to;
for (int i = 0; i < V; ++i)
{
if ( (source == VectorHeadPtr[i].GateName) || (source == VectorHeadPtr[i].OutputName) )
{
from = i;
}
else if (( destination == VectorHeadPtr[i].GateName) || (destination == VectorHeadPtr[i].OutputName) )
{
to = i;
}
}
AdjListNode* newNode = newAdjListNode(to, destination);
newNode->next = VectorHeadPtr[from].head;
VectorHeadPtr[from].head = newNode;
}
/*
* Print the graph
*/
void printGraph()
{
for (int i = 0; i < circGates; i++)//meno ooutput+input
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
cout<<endl<<"Gate connections for "<<VectorHeadPtr[i].GateName;
while (Ptr)
{
cout <<"-> "<< Ptr->name;
Ptr = Ptr->next;
}
cout<<" Output name is:"<<VectorHeadPtr[i].OutputName<<endl;
}
}
void calcGateVal()
{
vector<bool> Val={0, 1, 0};
vector<bool> Op;
for (int i = 0; i < circOutputs; i++)
{
ioPuts.pop_back();
}
for (int i = 0; i < circGates; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
if (Ptr->name.at(0) == 'I')
{
for (int j = 0; j < ioPuts.size(); j++)
{
if (Ptr->name == ioPuts[j])
{
Ptr->gValue = Val[j];
}
}
}
Ptr = Ptr->next;
}
}
for (int i = 0; i < PrimaryInputs; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
Op.push_back(Ptr->gValue);
Ptr = Ptr->next;
}
VectorHeadPtr[i].result = VectorHeadPtr[i].ptrf(Op);
cout<<"Gate Value is: "<<VectorHeadPtr[i].result<<" OutputName: "<<VectorHeadPtr[i].OutputName<<" GateName: "<<VectorHeadPtr[i].GateName<<endl;
Op.clear();
}
for (int i = PrimaryInputs; i < V; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
for (int j = 0; j < PrimaryInputs; j++)
{
if (Ptr->name == VectorHeadPtr[j].OutputName)
{
Ptr->gValue = VectorHeadPtr[j].result;
}
}
Ptr = Ptr->next;
}
}
for (int i = PrimaryInputs; i < circGates; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
Op.push_back(Ptr->gValue);
Ptr = Ptr->next;
}
VectorHeadPtr[i].result = VectorHeadPtr->ptrf(Op);
Op.clear();
}
}
void displayOutput()
{ cout<<endl;
for (int i = 0; i < circGates; i++)
{
cout<<"Value of outputs are ("<<VectorHeadPtr[i].GateName<<") "<<VectorHeadPtr[i].OutputName<<": "<<VectorHeadPtr[i].result<<endl;
}
}
};
/*
* Main
*/
int main()
{
vector<string> G_d;
G_d.push_back("AND 2 U0 I0 I1 N0");
G_d.push_back("XOR 2 U1 N0 I2 O0");
G_d.push_back("AND 2 U2 N0 I2 N1");
G_d.push_back("AND 2 U3 I0 I1 N2");
G_d.push_back("OR 2 U4 N1 N2 O1");
Graph gh(G_d);
gh.calcGateVal();
gh.displayOutput();
gh.printGraph();
// print the adjacency list representation of the above graph
return 0;
}
I think your code does not produce what you say it produces. Please see here:
http://coliru.stacked-crooked.com/a/405b04c8d9113790 - Check the output of this
Why do you want to convert strings to integers with strtoi with your case comparisons? :
case strtoi("NAND"):
a better approach would be strcmp or store each in a string perhaps a look up table and do a "==" equal equal comparison which is overloaded for strings.
Consider passing your vectors and objects around by reference rather than value, you might be expecting a return in your object but since you pass by value you never see them and this also avoids the overhead of making a copy of the vectors.

llvm "replaceinstwithvalue" does not work

I am a llvm newbie.
I am trying to write a llvm pass to optimize for algebraic identities in a function (like, if my function has an instruction a = b * 0, my pass should replace all following uses of "a" with 0).
So, my pass looks like follows:-
...
for (Function::iterator f_it = F.begin(), f_ite = F.end(); f_it != f_ite; ++f_it) {
for(BasicBlock::iterator b_it = f_it->begin(), b_ite = f_it->end(); b_it != b_ite; ++b_it) {
if(op->getOpcode() == Instruction::Mul) {
if(ConstantInt *CI_F = dyn_cast<ConstantInt>(&*b_it->getOperand(0))) {
if(CI_F->isZero()) {
firstop_zero = 1;
}
}
if(ConstantInt *CI_S = dyn_cast<ConstantInt>(&*b_it->getOperand(1))) {
if(CI_S->isZero()) {
secop_zero = 1;
}
}
if(first_zero || second_zero) {
errs()<<"found zero operand\n";
ReplaceInstWithValue(b_it->getParent()->getInstList(),b_it,(first_zero?(&*b_it->getOperand(1)):(&*b_it->getOperand(0))));
}
}
}
}
I can see that my comment "found zero operand gets printed out on std-err, but I can't see the replacement in the resulting .bc's disassembly.
What am I missing here? Any help is sincerely appreciated.
Thanks a lot!
Praveena
Try
for (Function::iterator f_it = F.begin(), f_ite = F.end(); f_it != f_ite; ++f_it) {
for(BasicBlock::iterator b_it = f_it->begin(), b_ite = f_it->end(); b_it != b_ite; ++b_it) {
Instruction *I = *b_it;
Value *Zeroval;
if(op->getOpcode() == Instruction::Mul) {
if(ConstantInt *CI_F = dyn_cast<ConstantInt>(&*b_it->getOperand(0))) {
if(CI_F->isZero()) {
firstop_zero = 1;
Zeroval = CI_F;
}
}
if(ConstantInt *CI_S = dyn_cast<ConstantInt>(&*b_it->getOperand(1))) {
if(CI_S->isZero()) {
secop_zero = 1;
ZeroVal = CI_S;
}
}
if(first_zero || second_zero) {
errs()<<"found zero operand\n";
I->ReplaceAlluseswith(ZeroVal);
}
}
}
}

Why I can not output paths of the maze?Who can tell me?Please

about data structures,why i can't output paths of the maze? I use the stack to storage the information of the current position.Read map of maze through a text file,if the position cant't pass
will be marker by "#",it is a wall.the way marker by "+". written in C++.
PS:My English is very poor.
//stack.h
#ifndef _STACK_H_
#define _STACK_H_
#include<iostream>
#include<stdlib.h>
const int SIZE = 81;
using namespace std;
typedef struct
{
int x;
int y;
}PosType;
typedef struct SElemType{
int ord;//steps
PosType seat;//coordinate
int di;//direction
}SElemType;
typedef struct SqStack{
SElemType *base;
SElemType *top;
int StackSize;
}SqStack;
void Init_S(SqStack &S)
{
S.base = new SElemType[SIZE];
if(!S.base)
exit(EXIT_FAILURE);
S.top = S.base;
S.StackSize = SIZE;
}
bool StackEmpty(SqStack S)
{
if(S.top = S.base)
return true;
return false;
}
void Push(SqStack &S,SElemType e)
{
SElemType *newbase;
if(S.top-S.base>=S.StackSize)
{
newbase = new SElemType[S.StackSize*2];
if(!S.base)
exit(EXIT_FAILURE);
for(int i(0);i<S.top-S.base;i++)
*(newbase+i) = *(S.base+i);
delete[]S.base;
S.base = newbase;
S.top = S.base+S.StackSize;
S.StackSize *= 2;
}
*(S.top)++ = e;
}
void Pop(SqStack &S,SElemType e)
{
if(StackEmpty(S))
cout<<"empty stack!\n";
else
e = *(--S.top);
}
#endif
//maze.cpp
#include<iostream>
#include<cstdlib>
#include<fstream>
#include"stack.h"
using namespace std;
const int m = 10;
const int n = 10;
typedef char MazeG[m][n];
void Show_MG(MazeG MG)
{
for(int i(0);i<m;i++)
{
for(int j(0);j<n;j++)
{
cout<<MG[i][j];
}
cout<<"\t\n";
}
}
PosType Next(PosType &pos,int di)
{
PosType repos;
switch(di)
{
case 0://north
repos.x = pos.x-1;
repos.y = pos.y;
break;
case 1://east
repos.x = pos.x;
repos.y = pos.y+1;
break;
case 2://south
repos.x = pos.x+1;
repos.y = pos.y;
break;
case 3://west
repos.x = pos.x;
repos.y = pos.y-1;
break;
default:
break;
}
return repos;
}
int MazePath(MazeG &MG,PosType begin,PosType end)
{
PosType curpos = begin;
SqStack S;
Init_S(S);
SElemType e;
e.ord = 0;
do{
if(MG[curpos.x][curpos.y]=='*')
{
MG[curpos.x][curpos.y] = '+';
e.seat = curpos;
e.di = 0;
e.ord++;
Push(S,e);
if(curpos.x==end.x&&curpos.y==end.y)
{
cout<<"此迷宫的一条路径如下:(+标记为路径)\n";//the path of maze:
cout<<"走了"<<e.di<<"步到达出口\n";//The number of steps walked
Show_MG(MG);
return 0;
}
else
curpos = Next(curpos,e.di);
}
else
if(!StackEmpty(S))
{
Pop(S,e);
e.ord--;
while(e.di==3&&!StackEmpty(S))
{
MG[curpos.x][curpos.y] = '#';
Pop(S,e);
e.ord--;
}
if(e.di<3)
{
e.di++;
Push(S,e);
e.ord++;
curpos = Next(curpos,e.di);
}
}
}while(!StackEmpty(S));
cout<<"此迷宫没有入口到出口的路径!\n";//no path of the maze
//return -1;
}
int main()
{
MazeG MG;
PosType begin,end;
begin.x = 1; begin.y = 1;
end.x = 8; end.y = 8;
ifstream fin;
fin.open("file.txt");
if(!fin.is_open())
{
cout<<"erorr file!!\n";
exit(EXIT_FAILURE);
}
if(fin.good())
{
for(int i(0);i<m;i++)
for(int j(0);j<n;j++)
fin>>MG[i][j];
}
cout<<"迷宫图为:(*代表能通过)\n";//map of maze:('*' is means through)
Show_MG(MG);
cout<<begin.x<<begin.y<<end.x<<end.y<<endl;
fin.close();
MazePath(MG,begin,end);
return 0;
}
This is wrong
bool StackEmpty(SqStack S)
{
if(S.top = S.base)
return true;
return false;
}
It should be this
bool StackEmpty(SqStack S)
{
if(S.top == S.base) // == not =
return true;
return false;
}
Use == for equality not =.
Now,I understand my the error of code is that I mismatch the data will be stored by stack.
I have changed my code,that's right.
//stack.h
SElemType Gettop(SqStack S)
{
if(!Empty_S(S))
return *(S.top-1);
}
//maze_path.cpp
do{
if(MG[curpos.x][curpos.y]=='*')
{
MG[curpos.x][curpos.y] = '+';
e.seat = curpos;
e.di = 0;
e.ord++;
Push(S,e);
if(curpos.x==end.x&&curpos.y==end.y)
{
cout<<"此迷宫的一条路径如下:(+标记为路径)\n";//the path of maze:
cout<<"走了"<<e.di<<"步到达出口\n";//The number of steps walked
Show_MG(MG);
return 0;
}
else
curpos = Next(curpos,e.di);
}
else
if(!StackEmpty(S))
{
if(e.di<3)
{
e.ord++;
curpos = Next(curpos,e.di);
}
else
{
MG[curpos.x][curpos.y] = '#';
Pop(S,e);
e = Gettop(S);
}
}
}while(!StackEmpty(S));