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