Set function in c++ not working [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Im writing a Set class in c++(i know there is already a library this is an assignment) and similar to the one in C++ im writing a function to check if the entry being inputted is already in the set
void Set::insert(const Set::value_type& entry)
{
for (int i=0; i<used;i++)
{
if(data[i]!=entry && used<CAPACITY)
{
data[used] = entry;
used++;
}
else
{
throw "Out of capacity in Set and Intger already in Set";
}
}
}
What the function does is look if the number is in the set. If the number is not in the set and if used < capacity (meaning their is still room) then the number is inserted. When i use the insert function nothing happens. Could someone help me out. Maybe im approaching this the wrong way.

As written, when insert-ing to an empty Set, used will be 0, so the loop terminates without doing anything. You don't handle the case where the value wasn't found after the loop, so it never inserts.
Even if you switched to loop to CAPACITY, the inner check is going to fill the whole Set with the same value on first run (because the if check's block executes, but doesn't break the loop, so it stores the same value over and over until it fills the Set or finds itself), then on subsequent inserts, it will immediately raise an exception for being full. Perhaps you wanted something like this?
void Set::insert(const Set::value_type& entry)
{
// If you have a membership test function, you can reuse it here instead
// of including this loop, e.g.:
// if (this->contains(entry)) return;
for (int i=0; i < used;i++)
{
if (data[i] == entry) {
// value already in set, nothing to do
return;
}
}
// Not already in Set, add if we have room or raise exception
if (used < CAPACITY) {
data[used++] = entry;
return;
}
throw "Out of capacity in Set";
}

When the set is initially empty, so that used == 0, your loop doesn't do anything, because the i < used condition fails immediately. So you never add the new item to the set.
And if there are items in the set, the loop adds the new entry to the set if it's different from any existing element. It adds it repeatedly for each element that it's not equal to.
What you need to do is go through the entire set, and see if a match is found anywhere. If it makes it through the entire loop without finding a match, it adds the new entry.
void Set::insert(const Set::value_type& entry)
{
for (int i=0; i<used;i++)
{
if(data[i] ==entry)
{
return;
}
}
// Not found, add it
if (used < CAPACITY) {
data[used++] = entry;
} else
{
throw "Out of capacity in Set";
}
}

Related

C++ Queue error [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
This is my Queue declaration here
// TODO: Declare a queue here - e.g. as a global variable
queue<string>myQueue;
This here is where I think my problem is. Whenever I run the program, I get an error stating "deque iterator not dereferencable."
string receiveMessage()
{
string messageValue = noMessage; // Don't change this value unless there is a message - default is improtant
messageQueueMutex.lock();
try
{
// TODO: Set hasMessages to true if your queue is not empty, otherwise set it to false:
if(!myQueue.empty())
{
bool hasMessages = true;
}
else
{
bool hasMessages = false;
}
// TODO: Remove the first message from your queue and place it in messageValue:
messageValue = myQueue.front();
myQueue.pop();
}
catch (...)
{
cout << "Exception occurred - check your code!" << endl;
}
messageQueueMutex.unlock();
return messageValue;
}
You don't need to use unlock() here, std::mutex will automatically unlock when it goes out of scope. Also, hasMessages will not be accessible after the if-else statement b/c it is declared inside the scopes of the if-else statement. So, you need to do:
bool hasMessages;
if(!myQueue.empty())
{
hasMessages = true;
}
else
{
hasMessages = false;
}
If the queue is empty, this code will still attempt to remove the first element from the queue. If you don't believe me, just ask your rubber duck.
This is, of course, undefined behavior.

Segmentation fault on list in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm using a class which holds a private list:
class Set
{
private:
list<long long unsigned> ways; //holds tags of addresses
and as part of the class's functionality I'm managing a LIFO on the list 'ways':
list<long long unsigned>::iterator it = ways.begin();
while (it!= ways.end()) //looks for the tag in the list
{
if ((*it) == tag) //tag is found in this set. moves the tag to the end of the list
{
ways.erase(it);
ways.push_back(tag);
return true;
}
it++;
}
return false;
and:
if (occupied < maxWays) //if the set is not all used up just pushes tag in the end
{
ways.push_back(tag);
occupied++;
return false;
}
else // if used up pops the front member (the least recently used one)
{
ways.pop_front();
ways.push_back(tag);
}
return true;
Nothing else touches 'ways' and nothing else erases the class 'set'.
Multiple instances of the class 'set' are created at the beginning.
During operation I'm getting Segmentation Fault for
list<long long unsigned>::iterator it = ways.begin();
which occurs after a long run. Trying to print the address of 'ways' before this line shows that at the point that I'm about to get Segmentation Fault the address of 'ways' changed dramatically.
All the previous times it was around 0x6000xxxxx for each instance, and at that time it was 0x23.
I don't have a clue what can cause that, please assist.
It might be that you delete an element from the list, and then increment the iterator, which points to the deleted element.
You probably need to forward the iterator first, and then remove the previous, to achieve what you want.
See:
Can you remove elements from a std::list while iterating through it?
EDIT: See also the return value of erase(), and similar operations that modify the iterator bag.
http://www.cplusplus.com/reference/list/list/erase/
Are you initiliazing 'occupied' and 'maxWays' ? If not, see example where it fails as we are calling ways.pop_front() on empty list ways
class Set
{
public:
Set(int max)
{
maxWays = max;
occupied = 10; // Say randomly stored value 10 is more than maxWays = 5
}
bool search(long long tag)
{
list<long long unsigned>::iterator it = ways.begin();
while (it!= ways.end()) {
if ((*it) == tag) {
ways.erase(it);
ways.push_back(tag);
return true;
}
it++;
}
return false;
}
bool add(long long tag)
{
if (occupied < maxWays) {
ways.push_back(tag);
occupied++;
return false;
}
else {
ways.pop_front(); // may fail here
ways.push_back(tag);
}
return true;
}
private:
list<long long unsigned> ways;
int maxWays;
int occupied;
};
int main()
{
Set set(5);
cout << set.add(100) << endl;
return 0;
}

How to handle segmentation fault in an array C++

I am creating a program that finds the shortest path from one vertex to another that is based upon a set and tables that keep track vertex information as well as the shortest paths from one vertex to another. This is created using an array, NOT a linked list.
//--------------------------------------------------------------------------
// 'updatepaths' uses the newest vertex which was added to the Set to modify
// the distances of the remaining vertices (if smaller)
// in addition to the newly added vertex, it uses the Set, the Vertexinfo
// and the Shortpath tables
//--------------------------------------------------------------------------
void Paths::updatepaths(int addnode)
{
if (done.in(addnode)) //done is a set instance, checks if the value is in the set
{
for (int i = 0; i<VERTICES; i++)
{
if (shortpath[edgedata[addnode].path[i].vertexto].distance > edgedata[addnode].path[i].weight) //HERE IS THE ISSUE
{
shortpath[edgedata[addnode].path[i].vertexto].distance = edgedata[addnode].path[i].weight;
shortpath[edgedata[addnode].path[i].vertexto].via = addnode;
}
}
}
}
I realize that the code is quite difficult to read, but it's the only way to compare vertex distances to one another that I can think of -- the issue is that in the if statement, sometimes it will try to compare values that don't exist in the array.
For example, edgedata[addnode].path[0].weight may contain NO VALUE - thus my program throws an access violation (segmentation fault). I tried setting edgedata[addnode].path[i].weight != NULL in the if statement as well as 0, but you cannot use NULL during arithmetic and it won't ever be 0 if it doesn't exist.
How should I make it so that it won't try to compare values that don't exist? Thanks for the help.
If your logic is regularly hitting NULL objects, there may likely be larger design or implementation issues in your code, but the easiest thing to do here to patch over your immediate problem is to use std::array<>::at(), instead of std::array<>::operator[], and catch the out_of_range exceptions it can generate:
try {
if (shortpath.at(edgedata.at(addnode).path.at(i).vertexto).distance >
edgedata.at(addnode).path.at(i).weight)
{
shortpath.at(edgedata.at(addnode).path.at(i).vertexto).distance =
edgedata.at(addnode).path.at(i).weight;
shortpath.at(edgedata.at(addnode).path.at(i).vertexto).via = addnode;
}
}
catch (std::out_of_range const &oor) {
std::cerr << "Out of Range error: " << oor.what() << std::endl;
}
Alternately, you can short-circuit checks in your if statement along these lines (I probably missed a check or two here, so watch out):
if ((edgedata.size() >= addnode)
&& (edgedata[addnode].path.size() >= i)
&& (shortpath.size() >= edgedata[addnode].path[i].vertexto)
&& (shortpath[edgedata[addnode].path[i].vertexto].distance >
edgedata[addnode].path[i].weight))
{
shortpath[edgedata[addnode].path[i].vertexto].distance =
edgedata[addnode].path[i].weight;
shortpath[edgedata[addnode].path[i].vertexto].via = addnode;
}
When you write c++ code, you shoud use the c++ coding style firstly. For example, you can use the std::vector instead of array, then you shoud use the iterator to access the element of vector or use vec.at(i) because this two methods can check the boundary exceeded, In c,it has no way to do so

C++ do while loop

I have a vector holding 10 items (all of the same class for simplicity call it 'a'). What I want to do is to check that 'A' isn't either a) hiding the walls or b) hiding another 'A'. I have a collisions function that does this.
The idea is simply to have this looping class go though and move 'A' to the next position, if that potion is causing a collision then it needs to give itself a new random position on the screen. Because the screen is small, there is a good chance that the element will be put onto of another one (or on top of the wall etc). The logic of the code works well in my head - but debugging the code the object just gets stuck in the loop, and stay in the same position. 'A' is supposed to move about the screen, but it stays still!
When I comment out the Do while loop, and move the 'MoveObject()' Function up the code works perfectly the 'A's are moving about the screen. It is just when I try and add the extra functionality to it is when it doesn't work.
void Board::Loop(void){
//Display the postion of that Element.
for (unsigned int i = 0; i <= 10; ++i){
do {
if (checkCollisions(i)==true){
moveObject(i);
}
else{
objects[i]->ResetPostion();
}
}
while (checkCollisions(i) == false);
objects[i]->SetPosition(objects[i]->getXDir(),objects[i]->getYDir());
}
}
The class below is the collision detection. This I will expand later.
bool Board::checkCollisions(int index){
char boundry = map[objects[index]->getXDir()][objects[index]->getYDir()];
//There has been no collisions - therefore don't change anything
if(boundry == SYMBOL_EMPTY){
return false;
}
else{
return true;
}
}
Any help would be much appreciated. I will buy you a virtual beer :-)
Thanks
Edit:
ResetPostion -> this will give the element A a random position on the screen
moveObject -> this will look at the direction of the object and adjust the x and Y cord's appropriately.
I guess you need: do { ...
... } while (checkCollisions(i));
Also, if you have 10 elements, then i = 0; i < 10; i++
And btw. don't write if (something == true), simply if (something) or if (!something)
for (unsigned int i = 0; i <= 10; ++i){
is wrong because that's a loop for eleven items, use
for (unsigned int i = 0; i < 10; ++i){
instead.
You don't define what 'doesn't work' means, so that's all the help I can give for now.
There seems to be a lot of confusion here over basic language structure and logic flow. Writing a few very simple test apps that exercise different language features will probably help you a lot. (So will a step-thru debugger, if you have one)
do/while() is a fairly advanced feature that some people spend whole careers never using, see: do...while vs while
I recommend getting a solid foundation with while and if/else before even using for. Your first look at do should be when you've just finished a while or for loop and realize you could save a mountain of duplicate initialization code if you just changed the order of execution a bit. (Personally I don't even use do for that any more, I just use an iterator with while(true)/break since it lets me pre and post code all within a single loop)
I think this simplifies what you're trying to accomplish:
void Board::Loop(void) {
//Display the postion of that Element.
for (unsigned int i = 0; i < 10; ++i) {
while(IsGoingToCollide(i)) //check is first, do while doesn't make sense
objects[i]->ResetPosition();
moveObject(i); //same as ->SetPosition(XDir, YDir)?
//either explain difference or remove one or the other
}
}
This function name seems ambiguous to me:
bool Board::checkCollisions(int index) {
I'd recommend changing it to:
// returns true if moving to next position (based on inertia) will
// cause overlap with any other object's or structure's current location
bool Board::IsGoingToCollide(int index) {
In contrast checkCollisions() could also mean:
// returns true if there is no overlap between this object's
// current location and any other object's or structure's current location
bool Board::DidntCollide(int index) {
Final note: Double check that ->ResetPosition() puts things inside the boundaries.

CLI/C++ Tetris block crashes when check if cell is occupied is empty MSVisualStudio 2008

Here is my code for checking if future move is legal, I have assumed its legal and copied move into mySquares array. I then call this method in the game cycle set in the form and in the timer handler which is:
canvas->drawGrid();
testBlock->drawBlock();
testBlock->moveDown();//this method has checkBounds for when hit sides, top & bottom
if(newBlock->canMoveDown()==false)
{
newBlock->addMySelfToGameBoard();
mainGameBoard->updateGrid();
}
//timer1 handler finish
bool TTetrisBlock::canMoveDown()
{
array<Point>^ temporaryCopy = gcnew array<Point>(4);
bool canGoDown = true;
for(int i=0;i<mySquares->Length;i++)
{
//Set future move
temporaryCopy[i].X = mySquares[i].X;
temporaryCopy[i].Y = mySquares[i].Y+1;
}
//Check if future move cells are full, if not assign values to mySquares
//Check if future move is legal
for(int j=0;j<temporaryCopy->Length;j++)
{
if(gameBoard->isCellOccupied(temporaryCopy[j].X,temporaryCopy[j].Y) == true)
{
mySquares[j].X = temporaryCopy[j].X;
mySquares[j].Y = temporaryCopy[j].Y;
}
}
return canGoDown;
}
//end of moveDown
in my gameboard class i have the method which checks if TCell is occupied or not. TGameBoar holds an array of TCells which has a color and bool isOccupied = false;
bool TGameBoard::isCellOccupied(int c,int r)
{
//Checks if TCell is occupied
return myGrid[c,r]->getIsOccupied();
}
It Crashes and indicates here was the problem, Im currently learning C++ at school. I would appreciate some help. I am also struggling with the Keydown for moving left and right using e->KeyData == Keys::Left) etc. and creating a newblock when gone through loop.
I have my project rar if you want to check it out. I have all the classes done, its just putting it together is the hard bit.
Project Tetris
I see three problems.
First you should only move mySquares when isCellOccupied returns false (not true as you currently have it). I suspect this is the cause of your crash as it looks like you will be moving a block into a cell that is already occupied.
Second, when isCellOccupied returns true you should set canGoDown to false and break out of your for loop (or better yet, make canGoDown (==true) an additional condition of your for loop i.e. j < temporaryCopy->Length && canGoDown). As it is, your function always return true because it is never set to false and that can't be right.
Just making an assumption here, but don't all mySquares consist of 4 elements? You are initializing temporaryCopy with 4 elements but it isn't clear whether mySquares has 4 elements. If not, this could be dangerous as in your first loop you are looping on mySquares->Length and addressing temporaryCopy with that index value, which could be out of range. And then later doing the opposite. It might be better to use a constant (4) in all all loops or better yet, always use mySquares->Length (especially when creating the temporaryCopy array) to ensure that both arrays contain the same number of elements.