Context
I have my own implementation of binary heap with decrease-key functionality. I'm using it on my Contraction Hierarchies implementation. When initializing a BinaryHeap, all works normally, but after the construction finishes, all the values of the BinaryHeap are setted to 0 (or 0 like values) and thus heap property no longer holds. I think it could be related to the usage of new
method
Details of the error
In BinaryHeap class, the variable that holds the information of the heap is items_
, a vector of pointer to Items<payload=int, value=float>
. When calling BinaryHeap(pairs, handles)
from a vector of pairs (62 elements) with negative and positive values, items_
is correctly setted inside the constructor, and check()
(check heap property) runs perfectly. Outside the constructor, I called check()
inmediately after, and it fails (heap property no longer holds). All values are now 0 or 0-ish (3e-41) and then the comparision assert(!less(index, parent))
fails (for some item, 0 < 3e-41). The vector items_ is still size 62.
Things I've tried:
- With gdb, I checked the variables of the binary heap, and items_ is still a valid vector with 62 items, but all values are 0 or 0-ish values (3e-41). No memory leaks, but the information of the heap is lost.
- If I run this binary heap implementation on an isolated test environment, this doesn't happen. I'm not including the whole BinaryHeap implementation, but I've tested it in all the basic cases and it works fine with no memory leaks.
template <class Payload, class Value>
struct Item{
Payload id;
Value value;
int index;
Item(Payload id=-1, Value value=10, int index=1) : id(id), value(value), index(index) {};
};
template <class Payload, class Value>
class BinaryHeap {
public:
BinaryHeap(){
items_.resize(1);
}
// Builds a BinaryHeap from a vector of pairs
BinaryHeap(vector<std::pair<Payload, Value>> pairs, vector<Item<Payload, Value>*>& handles)
{
items_.resize(pairs.size()+1);
for (size_t i = 0; i < pairs.size(); i++)
{
items_[i+1] = new Item<Payload, Value>(pairs[i].first, pairs[i].second, i+1);
handles[i] = items_[i+1];
}
for (size_t i = items_.size()/2; i > 0 ; i--)
{
sink_down(i);
}
// works fine
check();
}
void check() const {
// check if heap property holds
if (size() > 1)
{
for (int index = 2; index <= size(); index++) {
int parent = parentOf(index);
assert(!less(index, parent));
assert(items_[index]->index == index);
}
}
}
int size() const {
return items_.size()-1;
}
private:
std::vector<Item<Payload, Value>*> items_;
bool less(int i1, int i2) const {
return items_[i1]->value < items_[i2]->value;
}
// Contraction hierarchies implementation, pqueue is a BinaryHeap.
pqueue = BinaryHeap(pairs, handles_CH);
// raises error
pqueue.check();