Array String null - c++

Why does my IntForItem1 go over the max lenght of arrayStrings???
int TotalItems = 0, IntForItem1 = 0;
struct Item
{
int Index;
std::string* stringArray = new std::string[555]; //random value coz it will change in GetItems right?
};
Item item[120];
int AddNewItem(int i, int Index, std::string stringarray[])
{
item[i].Index = Index;
item[i].stringArray = stringarray;
return (i + 1);
}
void GetItems()
{
int i = 0;
std::string * test = new std::string[4]{ "1", "2", "3", "4"};
i = AddNewItem(i, IntForItem1, test);
TotalItems = i;
}
int main()
{
GetItems();
while (true)
{
system("CLS");
for (int i = 0; i < TotalItems; i++)
std::cout << item[i].stringArray[item[i].Index].c_str();
while (true)
{
if (GetAsyncKeyState(VK_LEFT) & 1)
{
if (item[0].Index <= 0)
item[0].Index = 0;
else
item[0].Index -= 1;
break;
}
else if (GetAsyncKeyState(VK_RIGHT) & 1)
{
if (item[0].Index >= sizeof(item[0].stringArray))
item[0].Index = sizeof(item[0].stringArray);
else
item[0].Index += 1;
break;
}
}
}
Sleep(1);
return 0;
}

sizeof(item[0].stringArray) in your code is the size of the string pointer, not the size of the space you set.
You can try this.
In additon, you should pay attention to the size of your array, otherwise you will always right-click the size of the array, can cause array crossing bounds, causing program errors.

Related

TSP recursive solution to its iterative form

I have a function which returns the shortest distance possible between n cities. AKA Travelling salesman problem.
int tsp(int mask, int pos, int n)
{
if (mask == VISITED_ALL)
{
return dist[pos][0];
}
int result = 2147483647;
for (int i = 0; i < n; i++)
{
if ((mask & (1 << i)) == 0)
{
int new_result = dist[pos][i] + tsp(mask | (1 << i), i, n);
result = min(result, new_result);
}
}
return result;
}
I would like to modify this recursive solution to iterative form, however I am struggling to do so. I am following this guide which describes conversion from recursive solution to iterative with couple of exapmles https://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and
THIS is what I've tried, but doesn't seem to work
int tspIterative(int mask, int pos, int n)
{
struct MyStructure
{
int mask;
int pos;
int n;
int new_result;
int result;
int stage;
};
int retVal = 0;
stack<MyStructure> myStack;
MyStructure currentStruct;
currentStruct.mask = mask;
currentStruct.pos = pos;
currentStruct.n = n;
currentStruct.new_result = 0;
currentStruct.result = 2147483647;
currentStruct.stage = 0;
myStack.push(currentStruct);
while (myStack.empty() != true)
{
currentStruct = myStack.top();
myStack.pop();
switch (currentStruct.stage)
{
case 0:
if (currentStruct.mask == VISITED_ALL)
{
retVal = dist[pos][0];
continue;
}
else
{
currentStruct.stage = 1;
myStack.push(currentStruct);
for (int i = 0; i < currentStruct.n; i++)
{
if ((currentStruct.mask & (1 << i)) == 0)
{
MyStructure newStruct;
newStruct.mask = currentStruct.mask | (1 << i);
newStruct.pos = i;
newStruct.n = currentStruct.n;
newStruct.result = currentStruct.result;
newStruct.new_result = currentStruct.new_result;
newStruct.stage = 0;
myStack.push(newStruct);
}
}
continue;
break;
case 1:
for (int i = 0; i < currentStruct.n; i++)
{
if ((currentStruct.mask & (1 << i)) == 0)
{
currentStruct.new_result = dist[currentStruct.pos][i] + retVal;
currentStruct.result = min(currentStruct.result, currentStruct.new_result);
retVal = currentStruct.result;
}
}
continue;
break;
}
}
return retVal;
}
}
Okay, so I have figured it out. Here's my solution if anyone's interested.
int tspIterative(int mask, int pos, int n)
{
struct MyStructure
{
int mask;
int pos;
int n;
int new_result;
int result;
int nextPos;
int stage;
};
int retVal = 0;
int k = 0;
stack<MyStructure> myStack;
MyStructure currentStruct;
currentStruct.mask = mask;
currentStruct.pos = pos;
currentStruct.n = n;
currentStruct.new_result = 0;
currentStruct.result = 2147483647;
currentStruct.nextPos = 0;
currentStruct.stage = 0;
myStack.push(currentStruct);
while (myStack.empty() != true)
{
currentStruct = myStack.top();
myStack.pop();
switch (currentStruct.stage)
{
case 0:
{
jump:
if (currentStruct.mask == VISITED_ALL)
{
retVal = dist[currentStruct.pos][0];
continue;
}
else
{
currentStruct.stage = 1;
myStack.push(currentStruct);
for (int i = currentStruct.nextPos + k; i < currentStruct.n; i++)
{
if ((currentStruct.mask & (1 << i)) == 0)
{
MyStructure newStruct;
newStruct.mask = (currentStruct.mask) | (1 << i);
newStruct.pos = i;
newStruct.n = currentStruct.n;
newStruct.result = 2147483647;
newStruct.new_result = 0;
newStruct.nextPos = 0;
newStruct.stage = 0;
currentStruct = myStack.top();
myStack.pop();
currentStruct.nextPos = i;
myStack.push(currentStruct);
myStack.push(newStruct);
break;
}
}
continue;
}
break;
}
case 1:
{
k = 0;
for (int i = currentStruct.nextPos + k; i < currentStruct.n; i++)
{
if ((currentStruct.mask & (1 << i)) == 0)
{
if (k > 0)
{
goto jump;
}
currentStruct.new_result = dist[currentStruct.pos][i] + retVal;
currentStruct.result = min(currentStruct.result, currentStruct.new_result);
retVal = currentStruct.result;
k = 1;
}
}
continue;
break;
}
}
}
return retVal;
}

How does the [] operator for a dictionary know if it is being referenced or assigned?

#ifndef _LIBCPP_HASH
#define _LIBCPP_HASH
#include <iostream>
#include <string>
#include <string.h>
#include <iomanip>
#define PERTERB_SHIFT 5
using namespace std;
int FAIL = 0;
template <typename myType>
class HashMap
{
public:
HashMap()
{
Size = 8;
Resize = 2;
Keys = new int[8];
Values = new myType[8];
typesize = sizeof(myType);
Fill = 0;
memset(Keys, -1, 32);
memset(Values, 0, 8 * typesize);
}
~HashMap()
{
delete[] Keys;
delete[] Values;
}
HashMap(const HashMap &table)
{
Size = table.Size;
Keys = table.Keys;
Values = table.Values;
}
int GetSize() { return Size; }
// can't return get(key) because no binding of reference int to temporary int, so has the same body as get..
myType &operator[] (int hash)
{
register size_t perterb = hash;
register unsigned long j = 0;
register int temp = 0;
register int index = 0;
while ( Keys[index] != hash && Keys[index] != -1)
{
j = 5 * j + 1 + perterb;
perterb >>= PERTERB_SHIFT;
index = j % (2 << Resize);
//cout << "j : " << j << " temp: " << temp << " hash: " << hash << " index: " << index << endl;
}
if (Fill == (int)(Size * 2 / 3))
{
cout << "here" << endl;
Resize <<= 1;
int* tempkey = new int[Size*2];
myType* tempvalue = new myType[Size*2];
memset(tempkey, -1, Size*8);
memset(tempvalue, 0, Size*2*typesize);
copy(Keys, Keys + Size, tempkey);
copy(Values, Values + Size, tempvalue);
delete[] Values; delete[] Keys;
Keys = tempkey; Values = tempvalue;
Size <<= 1;
}
if (Keys[index] != hash) Fill ++;
Keys[index] = hash;
return Values[index];
}
bool insert(int key, myType value)
{
int index = key % Size;
short temp = 0;
while ((Keys[index] != key) && (Keys[index] != -1) && temp < Size)
{
index ++;
temp ++;
}
if (temp == Size)
{
int s = static_cast<int>(Size*4);
int* tempkey = new int[s];
myType* tempvalue = new myType[s];
for (int i = Size; i < s; i++)
{
tempkey[i] = -1;
tempvalue[i] = 0;
}
copy(Keys, Keys + Size, tempkey);
copy(Values, Values + Size, tempvalue);
delete[] Values; delete[] Keys;
Size *= 4;
Keys = tempkey;
Values = tempvalue;
}
Keys[index] = key;
Values[index] = value;
return true;
}
myType get(int key)
{
int index = key % Size;
short count = 0;
while (Keys[index] != key && count < Size)
{
index ++;
count ++;
}
if (count == Size)
{
try
{
throw key;
}
catch (int er)
{
cout << "KeyError: " << er << endl;
}
return FAIL;
}
return Values[index];
}
myType pop(int key)
{
int index = key % Size;
short count = 0;
while (Keys[index] != key && count < Size)
{
index ++;
count ++;
}
if ( count == Size )
{
try
{
throw key;
}
catch (int er)
{
cout << "KeyError: " << er << endl;
}
return FAIL;
}
myType temp = Values[index];
Values[index] = 0;
Keys[index] = -1;
return temp;
}
void Print()
{
cout << "index\t" << "key\t" << "value\t" << endl;
for (int i = 0; i < Size; i++)
{
cout << i << "\t" << Keys[i] << "\t" << Values[i] << "\t" << endl;
}
}
private:
int Size;
int Resize;
int* Keys;
myType* Values;
short typesize;
int Fill;
};
#endif
This is my code currently. The hash function is based off of Python dictionaries. The issue arises when trying to reference a hashmap entry after it has been inserted. If there was a collision during insertion, the [] operator will treat the reference as if it is trying to insert the value again and will stop at the first key = -1, instead of iterating until it finds the hash value in the key array. I'm able to address this issue with insert(), pop(), and get(), but I don't know how to deal with it for the [] operator, since it is used for both reference and assignments. It needs to know if it is followed by an assignment operator before it tries to either insert or get the hash.
I spent some time in the Python source code trying to figure out how they dealt with this issue but I couldn't figure it out.
I know this is a strange question, but I would really appreciate any help.
Your [] can return a proxy type, which in turn has an operator int()&& for reading and operator =(int const&)&& for writing.
There are issues with this in that it interacts with auto poorly, but it does work.
This is what std vector bool does to support bit compressed data. It was viewed as a mistake, but partly for unrelated reasons.

Recieving "string subscript out of range" error

Doing this assignment where I parse information into a struct and I keep recieving an error saying "string subscript out of range" when trying to test. Cant figure out where I went wrong.
here is the struct
struct baby_type {
std::string name;
std::vector<int> yearsCount;
int total;
} ;
here is my function
baby_type Parse_Line(const std::string line )
{
baby_type baby;
std::string name;
std::string year;// = "0000";
std::string total;
int i = 0;
int k = 1;
int LengthOfOccurences = 0;
int DigitOfOccurences = 0;
while (line.at(i) != ',') {
name[i] = line.at(i);
i++;
}
baby.name = name;
i++;
while (k < 100) {
if (line.at(i) == ',') {
year.resize(LengthOfOccurences);
baby.yearsCount.at(k) = std::stoi(year);
//year = "0000";
i++;
k++;
DigitOfOccurences = 0;
LengthOfOccurences = 0;
}
else {
year.at(DigitOfOccurences) = line.at(i);
i++;
LengthOfOccurences++;
}
}
int m = 0;
int LengthOfLine = line.length();
while (i < LengthOfLine) {
total.at(m) = line.at(i);
m++;
i++;
}
baby.total = std::stoi(total);
return baby;
}
If you create empty std::string objects and then assign characters to specific positions. std::strings don't work that way.
In your first while loop, use
name.append(1,line.at(i));
The '1' is necessary because there is no simple std::append with just a character as parameter.

LRU c++ program

I've been working on a program in one of my college classes. I have been having trouble with the implementation of my LRU code as it is not displaying any errors or anything, but compiles. There are two parts. The main that we input the values into, which we then specify which algorithm we want to use to find page faults. I know the main works, along with the FIFO algorithm, but I'm not getting anything with my LRU code (It compiles and "runs" but displays nothing as if I did not click to use the algorithm). Can anyone help me figure out what is wrong?
main.cpp
#include <iostream>
#include <string>
//#include "fifo.cpp"
#include "lru.cpp"
//#include "optimal.cpp"
using namespace std;
int main() {
// List of different variables
string pagestring;
int fs,pn[50], n;
// Prompt for page references
cout<<"Virtual Memory Simulation\nBy blah\n----------\nEnter the number of pages : " << endl;
cin >> n;
cout<<"\n-------------\nPlease enter a list of page numbers separated by commas.\n"<< endl;
cin>>pagestring;
// algorithm to use
char algo;
while (true) {
// Prompt algorithm to use
cout<<"----------\nPlease select an algorithm to use.\n\n1: First-In-First-Out (FIFO)\n2: Least-Recently-Used (LRU)\n3: Optimal\n0: Quit\n"<<endl;
cin>>algo;
if (algo == '1') {
//fifo(pagestring);
}
else if (algo == '2'){
LRU_Execute(pagestring, n);
}
else if (algo == '3'){
cout<<"Optimal Not yet coded"<<endl;
}
else if (algo == '0'){
break;
}
else {
cout<<"Invalid choice. Please try again."<<endl;
}
}
cout<<"Goodbye!!"<<endl;
};
LRU.cpp
#include <iostream>
#include <string>
using namespace std;
class pra
{
int fs,z;
int frame[50], frame1[50][2], pn[50], n, cnt, p, x;
public:
pra();
void init(string pagestring);
void getdata(string pagestring, int n);
void lru(int* pn, int n, string pagestring);
};
pra::pra()
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::init(string pagestring)
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::getdata(string pagestring, int n)
{
fs=3;
// index to loop through input string
int i = 0;
// current input string character
char z = pagestring[i];
int x = 0;
//cout << "\nEnter the page numbers : ";
while (z != '\0'){
// skip over commas and spaces
if (!(z == ',')) {
pn[x] = z;
x++;
// cout<<pn[x]<<"-This is pn[x]\n";
}
z = pagestring[++i];
}
//cout<<pn[x]<<"-This is pn[x] AGAIN\n";
this->lru(pn, n, pagestring);
}
void pra::lru(int* pn, int n, string pagestring)
{
init(pagestring);
int ind = 0, fault = 0, pi = 0, j, fn;
char i, z;
p = 0;
cnt = 0;
int min;
cout<<n<<"---"<<i<<" - "<<j<<" - "<<" - "<<fn<<" - "<<z;
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
pi = 0;
for (i = 0; i < n; i++)
{
j = 0;
if (ind > fs - 1)
ind = 0;
fault = 1;
min = 999;
while (j < fs)
{
if (frame1[j][0] = pn[pi])
{
fault = 0;
p++;
frame1[j][1] = p;
goto l2;
}
if (frame1[j][1] < min)
{
min = frame1[j][1];
fn = j;
}
j++;
}
j = 0;
while (j < fs)
{
if (frame1[j][0] = -1)
{
fault = 1;
fn = j;
goto l2;
}
j++;
}
ind++;
l2:
if (fault == 1)
{
p++;
frame1[fn][0] = pn[pi];
frame1[fn][1] = p;
cnt++;
}
cout << "\nElement: " << pn[pi];
pi++;
for (z = 0; z < fs; z++)
{
cout << "\t" << frame1[z][0];
}
if (fault == 1)
cout << "\t**Page Fault**";
else
cout << "\t--No Page Fault--";
}
cout << "\nTotal number of page faults: " << cnt;
cout << "\n";
}
void LRU_Execute(string pagestring, int n)
{
pra p;
int j, fault = 0, i, pi, z, fn, ind = 0, ans, ch;
p.getdata(pagestring, n);
//p.lru();
while (ans == 1);
//return 1;
}

Returning a value from a function to another function

I'm making a program where a user can move their character (the number 1) throughout an array that is printed to the screen. I ran into trouble when i tried checking to see if the next position was open in my moveRight function.
I want to return the value of the part of the array which is one space to the right of the 1. The reason I am trying to return the value of the next spot of the array is because I want to return that value to my drawBoard function so I can use that value to reprint the board making the one in that position. How would i return mB[i+1] -(the next value to the right of the 1) to my drawBoard function?
#include "stdafx.h"
#include <iostream>
#include "PlayerM.h"
using namespace std;
class Player {
public:
Player::Player(int b[]) //create a constructer to copy the values of b into mB
{
// copy b into the member array
for (int i = 0; i < 16; i++) {
mB[i] = b[i];
}
}
int moveUp();
void moveDown();
int moveRight();
void moveLeft();
private:
int mB[16];
};
int Player::moveUp() {
return 0;
}
void Player::moveDown() {
}
int Player::moveRight() {
for (int i = 0; i < 16; i++) //find the players pos on aray
{
if (mB[i] == 1 && i < 3) //if the player is eligible to move
{
mB[i] = 0;
mB[i + 1] = 1;
return mB[i + 1];
}
}
}
void Player::moveLeft() {
}
int drawBoard(int boardArray[16]) //draw the game board
{
for (int i = 0; i < 16; i++) //use a for loop to simply draw the game board (4x4)
{
cout << boardArray[i]; //ouput the storage id of the array
if (i == 3 || i == 7 || i == 11 || i == 15) //every 4 lines begin new line
{
cout << "\n";
}
}
return 0;
}
int main() {
int bArray[16] = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //create an array [16]
drawBoard(bArray); //send the aray to drawBoard ()
Player p(bArray); //send bArray to the p constructer
char m;
cin >> m;
if (m == 'W') {
p.moveRight();
}
char f;
cin >> f;
}
int Player::moveRight() {
for (int i = 0; i < 16; i++) //find the players pos on aray
{
if (mB[i] == 1 && i < 3) //if the player is eligible to move
{
mB[i] = 0;
mB[i + 1] = 1;
return mB[i + 1];
}
}
}
I think you want the following (given that the board is 4x4):
int Player::moveRight() {
for (int i = 0; i < 16; i++) //find the players pos on aray
{
if (mB[i] == 1 && (i%4) < 3) //if the player is eligible to move
{
mB[i] = 0;
mB[i + 1] = 1;
return mB[i + 1];
}
}
}
What changed: i < 3 to (i%4) < 3