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
users@gecode.org
https://www.gecode.org/mailman/listinfo/gecode-users

Reply via email to