Hello Steven,

the error observed occurs when
- using the C++ interface
- using set_max_objective
- lb = ub for at least one variable.

When the optimizer is created with nlopt::nlopt() this constructor calls
nlopt_set_munge(o, free_myfunc_data, dup_myfunc_data);

When using C++ the data passed as f_data to nlopt::set_max_objective is wrapped into a struct myfunc_data.

In case of a maximization problem function nlopt_optimize replaces the data in struct myfunc_data by a struct f_max_data.

If for one variable lb = ub in function nlopt_optimize this causes a call to function elimdim_func.

Here the variable opt pointing to struct f_max_data is copied and in nlpopt_copy the munge_copy function dup_myfunc_data is called.

dup_myfunc_data expects d->fdata to be a struct myfunc_data and not struct f_max_data and therefore sees a field munge_copy which does not exist in f_max_data.

This leads to the segmentation fault observed.

Best regards

Heinrich Schuchardt




On 23.07.2014 22:06, Heinrich Schuchardt wrote:
Dear maintainer,

when running a simple model against NLopt I received a segmentation
error with the following output of valgrind.

=== Valgrind output ===

Conditional jump or move depends on uninitialised value(s)
    at 0x4022F9: nlopt::opt::dup_myfunc_data(void*) (in /tmp/test)
    by 0x4E6F9D0: nlopt_copy (options.c:133)
    by 0x4E71B2B: nlopt_optimize (optimize.c:251)
    by 0x402A03: nlopt::opt::optimize(std::vector<double,
std::allocator<double> >&, double&) (in /tmp/test)
    by 0x401D08: main (in /tmp/test)

Conditional jump or move depends on uninitialised value(s)
    at 0x402306: nlopt::opt::dup_myfunc_data(void*) (in /tmp/test)
    by 0x4E6F9D0: nlopt_copy (options.c:133)
    by 0x4E71B2B: nlopt_optimize (optimize.c:251)
    by 0x402A03: nlopt::opt::optimize(std::vector<double,
std::allocator<double> >&, double&) (in /tmp/test)
    by 0x401D08: main (in /tmp/test)

Use of uninitialised value of size 8
    at 0x40231B: nlopt::opt::dup_myfunc_data(void*) (in /tmp/test)
    by 0x4E6F9D0: nlopt_copy (options.c:133)
    by 0x4E71B2B: nlopt_optimize (optimize.c:251)
    by 0x402A03: nlopt::opt::optimize(std::vector<double,
std::allocator<double> >&, double&) (in /tmp/test)
    by 0x401D08: main (in /tmp/test)


Process terminating with default action of signal 11 (SIGSEGV)
  Bad permissions for mapped region at address 0xFFEFFFCC0
    at 0xFFEFFFCC0: ???
    by 0x4E6F9D0: nlopt_copy (options.c:133)
    by 0x4E71B2B: nlopt_optimize (optimize.c:251)
    by 0x402A03: nlopt::opt::optimize(std::vector<double,
std::allocator<double> >&, double&) (in /tmp/test)
    by 0x401D08: main (in /tmp/test)

=== Makefile ===

LDFLAGS=`pkg-config nlopt --libs`
CPPFLAGS=`pkg-config nlopt --cflags`

all:
         @echo LDFLAGS=$(LDFLAGS)
         @echo CPPFLAGS=$(CPPFLAGS)

         g++ $(LDFLAGS) $(CPPFLAGS) Test.cc -o test
         ./test

=== Test.cc ===

#include <vector>
#include <nlopt.hpp>
#include <cstdlib>
#include <iostream>

class Problem {
public:
     Problem(double x0, double y0);
     virtual ~Problem();
     double getX0();
     double getY0();
private:
     Problem(const Problem&);
     double x0_;
     double y0_;
};

Problem::Problem(double x0, double y0)
         : x0_(x0), y0_(y0) {
}

Problem::~Problem() {
}

Problem::Problem(const Problem &p)
         : x0_(p.x0_), y0_(p.y0_) {
}

double Problem::getX0() {
     return x0_;
}

double Problem::getY0() {
     return y0_;
}

static double func(const std::vector<double> &x,
         std::vector<double> &grad, void *data) {
     Problem *p = static_cast<Problem *> (data);
     double x0 = p->getX0();
     double y0 = p->getY0();
     double objectiveValue
             = (x[0] - x0) * (x[0] - x0)
             + (x[1] - y0) * (x[1] - y0);

     if (!grad.empty()) {
         throw 0;
     }

     return objectiveValue;
}

int main(int argc, char *argv[]) {
     double minf;
     std::vector<double> lb(2);
     std::vector<double> ub(2);
     std::vector<double> x(2);
     Problem *p = new Problem(2, 1);

     lb[0] = 4;
     x[0] = 2.5;
     ub[0] = 4;
     lb[1] = -4;
     x[1] = 1.5;
     ub[1] = 4;

     nlopt::opt *opt = new nlopt::opt(
             nlopt::LN_COBYLA, 2);

     opt->set_lower_bounds(lb);
     opt->set_upper_bounds(ub);

     opt->set_max_objective(func, p);

     opt->set_ftol_abs(1e-7);
     opt->set_xtol_abs(1e-7);

     std::cout << "Optimization started." << std::endl;
     opt->optimize(x, minf);
     std::cout << "Optimization finished." << std::endl;

     std::cout << "x[0] = " << x[0] << std::endl;
     std::cout << "x[1] = " << x[1] << std::endl;

     delete p;

     return EXIT_SUCCESS;
}

=== EOF ===

Best regards

Heinrich Schuchardt


_______________________________________________
NLopt-discuss mailing list
[email protected]
http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/nlopt-discuss

Reply via email to