Hello,
I've implemented a custom propagator and brancher which are sharing a
data-structure (a matrix of values), To share the structure in an efficient
(and convenient) way I have looked at using LocalHandle and LocalObject. In MPG
(Sec 31.4, page 391) this is described how to be implemented, however I am
doing something wrong because I keep on getting some kind of memory error.
My main problem is with the notice for disposal (since external resources are
used). If I do not use home.notice(*this, AP_DISPOSE) (line 17 in attached
file), my program does run without errors, but I suspect it might lead to
memory leaks. I've tried figuring out how this should work, but I have yet to
find a full example using LocalHandle/LocalObject (i.e. together with a model)
and no previous issues around this.
I'm attaching a minimum failing example (main.cpp), I'm compiling it on ubuntu
using g++ version 5.4.0. and Gecode version 5.0.0 (I'm fairly sure, do not know
how to exactly check this) using the following command:
g++ -g -o main src/main.cpp -lgecodedriver -lgecodegist -lgecodesearch
-lgecodeminimodel -lgecodeint -lgecodekernel -lgecodesupport
and when running it I receive the following error (gdb output):
-----------------------------------------------------------------------------
Program received signal SIGSEGV, Segmentation fault.
Gecode::VarImp<Gecode::Int::IntVarImpConf>::update (sub=<synthetic pointer>,
home=...) at ./gecode/kernel/core.hpp:4438
4438 ./gecode/kernel/core.hpp: No such file or directory.
(gdb) where
#0 Gecode::VarImp<Gecode::Int::IntVarImpConf>::update (sub=<synthetic
pointer>, home=...) at ./gecode/kernel/core.hpp:4438
#1 Gecode::Space::update (sub=0x64e380, this=0x64e220) at
./gecode/kernel/var-imp.hpp:484
#2 Gecode::Space::_clone (this=0x63c6a0, share_data=share_data@entry=true,
share_info=share_info@entry=true) at gecode/kernel/core.cpp:584
#3 0x00007ffff776b813 in Gecode::Space::clone (share_info=true,
share_data=true, this=<optimized out>) at ./gecode/kernel/core.hpp:3262
#4 Gecode::Search::Sequential::BAB::next (this=0x64db38) at
./gecode/search/sequential/bab.hh:149
#5 Gecode::Search::WorkerToEngine<Gecode::Search::Sequential::BAB>::next
(this=0x64db30) at ./gecode/search/support.hh:86
#6 0x0000000000411ad9 in Gecode::Search::Base<MyScript>::next (this=<optimized
out>) at /usr/local/include/gecode/search/base.hpp:51
#7
Gecode::Driver::ScriptBase<Gecode::Driver::IgnoreStepOption<Gecode::IntMinimizeSpace>
>::runMeta<MyScript, Gecode::BAB, Gecode::SizeOptions,
Gecode::Driver::EngineToMeta> (o=..., s=0x63c6a0)
at /usr/local/include/gecode/driver/script.hpp:360
#8 0x0000000000408e15 in
Gecode::Driver::ScriptBase<Gecode::Driver::IgnoreStepOption<Gecode::IntMinimizeSpace>
>::run<MyScript, Gecode::BAB, Gecode::SizeOptions> (o=..., s=0x0)
at /usr/local/include/gecode/driver/script.hpp:274
#9 0x0000000000405536 in main (argc=1, argv=0x7fffffffe0d8) at src/main.cpp:63
-----------------------------------------------------------------------------
Any ideas on what might be the problem is greatly appreciated. My guess is that
perhaps the destructor of the LocalHandle (LH) class have to make sure dispose
is called on the LocalObject (LHO), however my skills in C++ and Gecode are
not enough to know how I can try this. If someone just have an implementation
using LocalHandles/LocalObjects which is working, just letting me have a look
on that would be very helpful!
Best regards,
Peter Backeman \
#include <gecode/driver.hh>
#include <gecode/minimodel.hh>
using namespace Gecode;
class LH : public LocalHandle {
public:
class LHO : public LocalObject {
public:
int* data;
int size;
LHO(Space& home, int size0) : LocalObject(home), size(size0) {
data = (int*)malloc(sizeof(int)*size*size);
// Removing this line makes the program work
home.notice(*this, AP_DISPOSE);
}
LHO(Space& home, bool share, LHO& d) : LocalObject(home,share,d), data(heap.alloc<int>(d.size*d.size)), size(d.size) {}
virtual LocalObject* copy(Space& home, bool share) {
return new (home) LHO(home,share,*this);
}
virtual size_t dispose(Space& home) {
home.ignore(*this, AP_DISPOSE);
free(data);
// heap.free<int>(data, size*size);
return sizeof(*this);
}
};
LH(Space& home, int size0) : LocalHandle(new (home) LHO(home, size0)) {};
LH(const LH& data) : LocalHandle(data) {};
};
class MyScript : public IntMinimizeScript {
public:
static const int count = 20;
IntVarArray V;
LH lh;
MyScript(const SizeOptions& opt) : IntMinimizeScript(opt), lh(*this, count) {
V = IntVarArray(*this, count*count);
for (int i=0; i<V.size(); i++)
V[i] = IntVar(*this, 0, 1);
branch(*this, V, INT_VAR_NONE(), INT_VAL_MIN());
}
MyScript(bool share, MyScript& H) : IntMinimizeScript(share, H), lh(*this, count) {
V.update(*this, share, H.V);
lh.update(*this, share, H.lh);
}
Space* copy(bool share) { return new MyScript(share, *this); }
IntVar cost(void) const { return V[0]; }
void print(std::ostream& os) const {}
};
int main(int argc, char* argv[]) {
SizeOptions opt("MyScript");
IntMinimizeScript::run<MyScript,BAB,SizeOptions>(opt);
return 0;
}
_______________________________________________
Gecode users mailing list
[email protected]
https://www.gecode.org/mailman/listinfo/gecode-users