Boost::Fibonacci_Heap::top() object destroyed before assignment - c++

I have the following loop in a class method:
vector<PuzzleImpl> PuzzleImpl::performMove()
{
//! Remove a single move from mMoves and store it in aMove.
MovesImpl aMove = mMoves.top();
mMoves.pop();
//! Cached local variables.
vector<size> soln = aMove.getSoln();
size RID = aMove.getRowID();
size CID = aMove.getColID();
size BID = aMove.getBlockID();
bool solvable = true;
//! Return Vector, will store all possible moves from aMove.
vector<PuzzleImpl> neighbours;
//! Build all Boards and update Moves Queue for a move from top of mMoves.
while (!soln.empty()) {
//! Store local copies to update without being destructive to original.
// Also reset updatedMoves and updatedBoard for next iteration.
fib_heap tempHeap = mMoves;
fib_heap updatedMoves;
Board<size> updatedBoard = mBoard;
//! Get a <value>, remove it form <soln>.
size value = soln.back();
soln.pop_back();
//! Update Board with the move.
updatedBoard.set(RID, CID, value);
//! Iterate through the mMoves queue and update for the removed move.
while (!tempHeap.empty()) {
//! Get an element, remove it from the heap.
MovesImpl temp = tempHeap.top();
tempHeap.pop();
//! If the temp object shares the same RID/CID/BID remove <value>.
if ((temp.getRowID() == RID) || (temp.getColID() == CID)
|| (temp.getBlockID() == BID)) {
temp.removeMove(value);
}
//! Check if we can solve the puzzle form this position. If you have
// a blank position left but there are have no moves from that
// position, a solution is unattainable. - HALT.
if (temp.getSolnSize() == 0) {
solvable = false;
break;
}
//! Add the Moves object to the updatedMoves Heap.
updatedMoves.push(temp);
}
//! If the puzzle is solvable from this position with the current move,
// generate new PuzzleImpl object using the Board and Moves Vec.
neighbours.push_back(PuzzleImpl(updatedBoard, updatedMoves, solvable));
}
//! Return the Vector containing all possible states from this move.
return neighbours;
}
The problem I have is in the line:
MovesImpl temp = tempHeap.top();
I get an access violation (Access violation reading location 0x0000000C.) stating that <src>'s memory can't be read and <this> is set to random values in memory. MovesImpl doesn't have any heap allocation, its stack based and I thus use the default assignment operator. I have specified the copy ctor.
Any ideas? Input greatly appreciated.
/Thanks!

Related

C++ LRU cache - need suggestions on how to improve speed

The task is to implement an O(1) Least Recently Used Cache
Here is the question on leetcode
https://leetcode.com/problems/lru-cache/
Here is my solution, while it is O(1) it is not the fastest implementationcould you give some feedback and maybe ideas on how can I optimize this ? Thank you !
#include<unordered_map>
#include<list>
class LRUCache {
// umap<key,<value,listiterator>>
// store the key,value, position in list(iterator) where push_back occurred
private:
unordered_map<int,pair<int,list<int>::iterator>> umap;
list<int> klist;
int cap = -1;
public:
LRUCache(int capacity):cap(capacity){
}
int get(int key) {
// if the key exists in the unordered map
if(umap.count(key)){
// remove it from the old position
klist.erase(umap[key].second);
klist.push_back(key);
list<int>::iterator key_loc = klist.end();
umap[key].second = --key_loc;
return umap[key].first;
}
return -1;
}
void put(int key, int value) {
// if key already exists delete it from the the umap and klist
if(umap.count(key)){
klist.erase(umap[key].second);
umap.erase(key);
}
// if the unordered map is at max capacity
if(umap.size() == cap){
umap.erase(klist.front());
klist.pop_front();
}
// finally update klist and umap
klist.push_back(key);
list<int>::iterator key_loc = klist.end();
umap[key].first = value;
umap[key].second = --key_loc;
return;
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
Here's some optimizations that might help:
Take this segment of code from the get function:
if(umap.count(key)){
// remove it from the old position
klist.erase(umap[key].second);
The above will lookup key in the map twice. Once for the count method to see if it exists. Another to invoke the [] operator to fetch its value. Save a few cycles by doing this:
auto itor = umap.find(key);
if (itor != umap.end()) {
// remove it from the old position
klist.erase(itor->second);
In the put function, you do this:
if(umap.count(key)){
klist.erase(umap[key].second);
umap.erase(key);
}
Same thing as get, you can avoid the redundant search through umap. Additionally, there's no reason to invoke umap.erase only to add that same key back into the map a few lines later.
Further, this is also inefficient
umap[key].first = value;
umap[key].second = --key_loc;
Similar to above, redundantly looking up key twice in the map. In the first assignment statement, the key is not in the map, so it default constructs a new value pair thing. The second assignment is doing another lookup in the map.
Let's restructure your put function as follows:
void put(int key, int value) {
auto itor = umap.find(key);
bool reinsert = (itor != umap.end());
// if key already exists delete it from the klist only
if (reinsert) {
klist.erase(umap[key].second);
}
else {
// if the unordered map is at max capacity
if (umap.size() == cap) {
umap.erase(klist.front());
klist.pop_front();
}
}
// finally update klist and umap
klist.push_back(key);
list<int>::iterator key_loc = klist.end();
auto endOfList = --key_loc;
if (reinsert) {
itor->second.first = value;
itor->second.second = endOfList;
}
else {
const pair<int, list<int>::iterator> itempair = { value, endOfList };
umap.emplace(key, itempair);
}
}
That's as far as you can probably go by using std::list. The downside of the list type is that there's no way to move an existing node from the middle to the front (or back) without first removing it and then adding it back. That's a couple of unneeded memory allocations to update the list. Possible alternative is that you just use your own double-linked list type and manually fixup the prev/next pointer yourself.
Here is my solution, while it is O(1) it is not the fastest implementation
could you give some feedback and maybe ideas on how can I optimize this ? Thank you !
Gonna take on selbie's point here:
Every instance of if(umap.count(key)) will search for the key and using umap[key] is the equivalent for the search. You can avoid the double search by assigning an iterator which points to the key by a single std::unordered_map::find() operation.
selbie already gave the code for int get()'s search, here's the one for void put()'s one:
auto it = umap.find(key);
if (it != umap.end())
{
klist.erase(it ->second);
umap.erase(key);
}
Sidecase:
Not applicable for your code as of now due to lack of input and output work, but in case you use std::cin and std::cout, you can disable the synchronization between C and C++ streams, and untie cin from cout as an optimization: (they are tied together by default)
// If your using cin/cout or I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);

undo operation implementation in 2048 game

I've implemented 2048 game in C++, github link : 2048
For implementing undo operation, i.e. going back to previous state of game, I'm maintaining a matrix for previous board configuration, but if I'm allowing many undo operations consecutively, I can't maintain that number of matrices.
What can be a way to improve this approach?
One way I thought was maintaining only the previous moves(up, down, left or right), but only this information can't help to regenerate the previous state, if I'm missing something in this approach or it can be extended, please suggest a way to do this.
You can store the board's current state into a stack, so every time the user makes a move, which will change the board state, just put it into a stack so you get a stack full of with matrix of board's current state of user's moves and ordered from recent one being on the top. So when you want to undo their latest move just pop from stack which will give you their latest operation.
...
std::stack<std::array<int, 16>> boardStates;
std::array<16, int> currentBoardState;
// whenever user makes a move
makeMove(currentBoardState)
//when they want to undo
tempBoardState = undoMove();
if(tempBoardState != nullptr)
{
currentBoardState = tempBoardState;
}
else
{
std::cout << "No previous move available" << std::endl
}
...
void makeMove(std::array<int, 16> currentState)
{
boardStates.push(currentState);
}
std::array<int, 16> undoMove()
{
if(!boardStates.empty())
{
return boardStates.pop();
}
return nullptr;
}
Implement an history, to store subsequent board status changes.
//maximum history size (can be whatever reasonable value)
const int MAX_UNDO = 2048;
//give a shorter name to the type used to store the board status
typedef std::array<int, 16> snapshot;
//use a double ended queue to store the board statuses
std::deque<snapshot> history;
//this function saves the current status, has to be called each time
//the board status changes, i.e. after the board initialization
//and after every player move
void save()
{
//make a copy of g, the current status
snapshot f;
std::copy(&g[0][0], &g[0][0] + 16, f.begin());
//push the copy on top
history.push_back(f);
//check history size
if(history.size() > MAX_UNDO)
{
//remove one element at the bottom end
history.pop_front();
}
}
bool undo()
{
//history must hold at least one element
//other than the current status copy
if(history.size() > 1)
{
//the top element of the queue always holds a copy of the
//current board status: remove it first
history.pop_back();
//now the top element is the previous status copy
snapshot f = history.back();
//copy it back to g
std::copy(f.begin(), f.end(), &g[0][0]);
//undo operation succedeed
return true;
}
//undo operation failed
return false;
}

Moving an object from one vector to another in C++ (LEMON library)

I am trying to use the LEMON library and I am running into an issue with an algorithm that I am trying to implement. The idea of this algorithm is that there is a vector of vectors of nodes and I want to move the nodes around to different vectors (color classes) with certain restrictions. Here is the code that implements my algorithm:
bool moveColor() {
// pick the smallest color class
sort(colors.begin(), colors.end(), vectorSort);
vector< vector< ListGraph::Node > >::iterator smallestColor = colors.begin();
// shuffle this class
random_shuffle(smallestColor->begin(), smallestColor->end());
// try to move any of the nodes to any bigger class
bool foundNode = false;
vector< ListGraph::Node >::iterator movingNode;
vector< vector< ListGraph::Node > >::iterator destinationClass;
for (movingNode = smallestColor->begin(); movingNode != smallestColor->end() && !foundNode; ++movingNode) {
for (destinationClass = colors.begin()+1; destinationClass != colors.end() && !foundNode; ++destinationClass) {
ListGraph::NodeMap<bool> filter(g, false);
vector< ListGraph::Node >::iterator classNode;
for (classNode = destinationClass->begin(); classNode != destinationClass->end(); ++classNode) {
filter[*classNode] = true;
}
filter[*movingNode] = true;
FilterNodes<ListGraph> subgraph(g, filter);
if (acyclic(subgraph)) {
foundNode = true;
}
}
}
// if a movable node was found, move it. otherwise return false
if (foundNode) {
destinationClass->push_back(*movingNode);
smallestColor->erase(movingNode);
if (smallestColor->empty()) {
colors.erase(smallestColor);
}
return true;
}
return false;
}
This function is called in main in a loop until a node was unable to be moved. The main issue I am having with the code is the section that actually moves a node from one vector to another:
if (foundNode) {
destinationClass->push_back(*movingNode);
smallestColor->erase(movingNode);
if (smallestColor->empty()) {
colors.erase(smallestColor);
}
return true;
}
This part doesn't seem to work because I think the node is being deconstructed when the erase function is being called. Here is a sample of the node ids before and after this function was called:
NEW ROUND
1
3
0
5 2
7 6 4
NEW ROUND
3
0 32701
5 2
7 6 4
As you can see, the id for the node that was moved is not correct (32701 instead of 1). Any help is appreciated.
The issue is actually here:
if (acyclic(subgraph)) {
foundNode = true;
}
When you locate the node, you don't break out of for loop, which makes movingNode iterator advance to next position in vector (smallestColor->end() in this case) before checking for !foundNode condition. In this case you have to break twice, as you are breaking from nested loop.
Optionally, you can store iterator that match criteria in separate variable to operate on outside the loop (different that one iterating over in for loop).
About the snippet you highlighted as potential source of issue:
destinationClass->push_back(*movingNode); is putting into destinationClass a copy of Node that movingNode iterator points to. That mean, copy constructor of Node is called. As Node has no user-defined copy constructor, compiler auto-generates one, that copy value of all members, so id value should be copied (of course if correct iterator is used for push_back). Of course original copy of node you are relocating is destructed with erase, but this does not affect new copy.

Pointer Issues (Probably Easy)

This is probably something really basic but I just can't seem to see where I'm messing up.
I've got a vector of Cubes (a child class of the abstract class Node) that each hold a body object that contains the x and z positions of its position on a plane. I'm attempting to move each in a "follow the leader" like style where the new position of a Cube is where the predecessor was before.
Since I'm using pointers this is where I'm a bit confused as at the moment, they are all going to the same position (wherever snake.x and snake.z is) so I know they are all pointing to the same piece of data.
Wonder what I need to alter so that each reflect the right coordinates.
void updateChildren()
{
Node * prevPiece;
typedef std::vector<Node*>::iterator It;
for(It curNode=nodes.begin(); curNode!=nodes.end(); ++curNode)
{
if (curNode == nodes.begin())
{
prevPiece = *curNode;
dynamic_cast<Cube*>(*curNode)->body.xPos = snake.xPos;
dynamic_cast<Cube*>(*curNode)->body.zPos = snake.zPos;
}
else
{
Node * tmp = *curNode;
dynamic_cast<Cube*>(*curNode)->body.xPos = dynamic_cast<Cube*>(prevPiece)->body.xPos;
dynamic_cast<Cube*>(*curNode)->body.zPos = dynamic_cast<Cube*>(prevPiece)->body.zPos;
prevPiece = tmp;
}
}
}
You assign the position of the the first Cube to the snake position, and then every subsequent Cube after that is just being assigned to this position.
Basically each iteration you are doing this:
current.position = previous.position.
previous = current; // The "previous position" has been overwritten
... next iterationn ...
current.position = previous.position; // previous.position is the new vlaue
previous = current;
...
You need to temporarily save the previous position before assigning it otherwise everything just get assigned to that.
You are modifying the head and then setting any subsequent element to the same values of the head.
A quick fix would be to do it the reverse way, from the bottom up, so that when an element is assigned a new value, we know that its old value is no longer needed. This is achieved using reverse_iterators:
void updateChildren()
{
for(auto curNode = nodes.rbegin(); curNode!=nodes.rend()-1; ++curNode)
{
dynamic_cast<Cube*>(*curNode)->body.xPos = dynamic_cast<Cube*>(*(curNode+1))->body.xPos;
dynamic_cast<Cube*>(*curNode)->body.zPos = dynamic_cast<Cube*>(*(curNode+1))->body.zPos;
}
dynamic_cast<Cube*>(nodes.front())->body.xPos = snake.xPos;
dynamic_cast<Cube*>(nodes.front())->body.zPos = snake.zPos;
}

How do I make make my hash table with linear probing more efficient?

I'm trying to implement an efficient hash table where collisions are solved using linear probing with step. This function has to be as efficient as possible. No needless = or == operations. My code is working, but not efficient. This efficiency is evaluated by an internal company system. It needs to be better.
There are two classes representing a key/value pair: CKey and CValue. These classes each have a standard constructor, copy constructor, and overridden operators = and ==. Both of them contain a getValue() method returning value of internal private variable. There is also the method getHashLPS() inside CKey, which return hashed position in hash table.
int getHashLPS(int tableSize,int step, int collision) const
{
return ((value + (i*step)) % tableSize);
}
Hash table.
class CTable
{
struct CItem {
CKey key;
CValue value;
};
CItem **table;
int valueCounter;
}
Methods
// return collisions count
int insert(const CKey& key, const CValue& val)
{
int position, collision = 0;
while(true)
{
position = key.getHashLPS(tableSize, step, collision); // get position
if(table[position] == NULL) // free space
{
table[position] = new CItem; // save item
table[position]->key = CKey(key);
table[position]->value = CValue(val);
valueCounter++;
break;
}
if(table[position]->key == key) // same keys => overwrite value
{
table[position]->value = val;
break;
}
collision++; // current positions is full, try another
if(collision >= tableSize) // full table
return -1;
}
return collision;
}
// return collisions count
int remove(const CKey& key)
{
int position, collision = 0;
while(true)
{
position = key.getHashLPS(tableSize, step, collision);
if(table[position] == NULL) // free position - key isn't in table or is unreachable bacause of wrong rehashing
return -1;
if(table[position]->key == key) // found
{
table[position] = NULL; // remove it
valueCounter--;
int newPosition, collisionRehash = 0;
for(int i = 0; i < tableSize; i++, collisionRehash = 0) // rehash table
{
if(table[i] != NULL) // if there is a item, rehash it
{
while(true)
{
newPosition = table[i]->key.getHashLPS(tableSize, step, collisionRehash++);
if(newPosition == i) // same position like before
break;
if(table[newPosition] == NULL) // new position and there is a free space
{
table[newPosition] = table[i]; // copy from old, insert to new
table[i] = NULL; // remove from old
break;
}
}
}
}
break;
}
collision++; // there is some item on newPosition, let's count another
if(collision >= valueCounter) // item isn't in table
return -1;
}
return collision;
}
Both functions return collisions count (for my own purpose) and they return -1 when the searched CKey isn't in the table or the table is full.
Tombstones are forbidden. Rehashing after removing is a must.
The biggest change for improvement I see is in the removal function. You shouldn't need to rehash the entire table. You only need to rehash starting from the removal point until you reach an empty bucket. Also, when re-hashing, remove and store all of the items that need to be re-hashed before doing the re-hashing so that they don't get in the way when placing them back in.
Another thing. With all hashes, the quickest way to increase efficiency to to decrease the loadFactor (the ratio of elements to backing-array size). This reduces the number of collisions, which means less iterating looking for an open spot, and less rehashing on removal. In the limit, as the loadFactor approaches 0, collision probability approaches 0, and it becomes more and more like an array. Though of course memory use goes up.
Update
You only need to rehash starting from the removal point and moving forward by your step size until you reach a null. The reason for this is that those are the only objects that could possibly change their location due to the removal. All other objects would wind up hasing to the exact same place, since they don't belong to the same "collision run".
A possible improvement would be to pre-allocate an array of CItems, that would avoid the malloc()s / news and free() deletes; and you would need the array to be changed to "CItem *table;"
But again: what you want is basically a smooth ride in a car with square wheels.