[PPL-devel] [GIT] ppl/ppl(pip): Added implementations for PIP_Problem swap and operator = methods.
Enea Zaffanella
zaffanella at cs.unipr.it
Thu Oct 8 20:44:02 CEST 2009
Module: ppl/ppl
Branch: pip
Commit: d5889e252f39916812471f4bf2da15d624accf00
URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=d5889e252f39916812471f4bf2da15d624accf00
Author: Enea Zaffanella <zaffanella at cs.unipr.it>
Date: Thu Oct 8 20:41:16 2009 +0200
Added implementations for PIP_Problem swap and operator= methods.
Added a few consistency checks in method OK().
Pointed out a resource management bug in copy constructor that can result
in memory corruption. Added test04() to pipproblem1.cc (currently commented
out) showing that a segmentation fault can be obtained when copying a
PIP_Problem object having a non-null solution tree.
---
src/PIP_Problem.cc | 54 ++++++++++++++++++++++++++++++++++++-
src/PIP_Problem.defs.hh | 2 +-
src/PIP_Problem.inlines.hh | 20 ++++++++++++++
tests/PIP_Problem/pipproblem1.cc | 36 +++++++++++++++++++++++++
4 files changed, 109 insertions(+), 3 deletions(-)
diff --git a/src/PIP_Problem.cc b/src/PIP_Problem.cc
index ffb093e..350f065 100644
--- a/src/PIP_Problem.cc
+++ b/src/PIP_Problem.cc
@@ -53,6 +53,8 @@ PPL::PIP_Problem::PIP_Problem(const PIP_Problem &y)
: external_space_dim(y.external_space_dim),
internal_space_dim(y.internal_space_dim),
status(y.status),
+ // FIXME: this causes sharing of the solution tree,
+ // possibly later resulting in memory corruption (double free).
current_solution(y.current_solution),
initialized(y.initialized),
input_cs(y.input_cs),
@@ -60,7 +62,7 @@ PPL::PIP_Problem::PIP_Problem(const PIP_Problem &y)
parameters(y.parameters),
initial_context(y.initial_context) {
PPL_ASSERT(OK());
- //FIXME: must also copy the solution tree
+ // FIXME: must also copy the solution tree
}
PPL::PIP_Problem::~PIP_Problem() {
@@ -164,7 +166,55 @@ PPL::PIP_Problem::optimizing_solution() const {
bool
PPL::PIP_Problem::OK() const {
- //FIXME
+#ifndef NDEBUG
+ using std::endl;
+ using std::cerr;
+#endif
+
+ if (external_space_dim < internal_space_dim) {
+#ifndef NDEBUG
+ cerr << "The internal space dimension of the PIP_Problem is "
+ << "greater than its external space dimension."
+ << endl;
+ ascii_dump(cerr);
+#endif
+ return false;
+ }
+
+ // Constraint system should be OK.
+ const dimension_type input_cs_num_rows = input_cs.size();
+ for (dimension_type i = input_cs_num_rows; i-- > 0; )
+ if (!input_cs[i].OK())
+ return false;
+
+ // Constraint system should contain no strict inequalities.
+ for (dimension_type i = input_cs_num_rows; i-- > 0; ) {
+ if (input_cs[i].is_strict_inequality()) {
+#ifndef NDEBUG
+ cerr << "The feasible region of the PIP_Problem is defined by "
+ << "a constraint system containing strict inequalities."
+ << endl;
+ ascii_dump(cerr);
+#endif
+ return false;
+ }
+ if (input_cs[i].space_dimension() > external_space_dim) {
+#ifndef NDEBUG
+ cerr << "The space dimension of the PIP_Problem is smaller than "
+ << "the space dimension of one of its constraints."
+ << endl;
+ ascii_dump(cerr);
+#endif
+ return false;
+ }
+ }
+
+ if (!parameters.OK())
+ return false;
+ if (!initial_context.OK())
+ return false;
+
+ // All checks passed.
return true;
}
diff --git a/src/PIP_Problem.defs.hh b/src/PIP_Problem.defs.hh
index beb291b..0096879 100644
--- a/src/PIP_Problem.defs.hh
+++ b/src/PIP_Problem.defs.hh
@@ -307,7 +307,7 @@ private:
Status status;
//! The current solution decision tree
- PIP_Tree_Node *current_solution;
+ PIP_Tree_Node* current_solution;
/*! \brief
A Boolean encoding whether or not internal data structures have
diff --git a/src/PIP_Problem.inlines.hh b/src/PIP_Problem.inlines.hh
index 44cbc94..61fe0a8 100644
--- a/src/PIP_Problem.inlines.hh
+++ b/src/PIP_Problem.inlines.hh
@@ -50,6 +50,26 @@ PIP_Problem::parameter_space_dimensions() const {
return parameters;
}
+inline void
+PIP_Problem::swap(PIP_Problem& y) {
+ std::swap(external_space_dim, y.external_space_dim);
+ std::swap(internal_space_dim, y.internal_space_dim);
+ std::swap(status, y.status);
+ std::swap(current_solution, y.current_solution);
+ std::swap(initialized, y.initialized);
+ std::swap(input_cs, y.input_cs);
+ std::swap(first_pending_constraint, y.first_pending_constraint);
+ std::swap(parameters, y.parameters);
+ std::swap(initial_context, y.initial_context);
+}
+
+inline PIP_Problem&
+PIP_Problem::operator=(const PIP_Problem& y) {
+ PIP_Problem tmp(y);
+ swap(tmp);
+ return *this;
+}
+
} // namespace Parma_Polyhedra_Library
namespace std {
diff --git a/tests/PIP_Problem/pipproblem1.cc b/tests/PIP_Problem/pipproblem1.cc
index bcd76f8..394a127 100644
--- a/tests/PIP_Problem/pipproblem1.cc
+++ b/tests/PIP_Problem/pipproblem1.cc
@@ -165,10 +165,46 @@ test03() {
return ok;
}
+bool
+test04() {
+ Variable i(0);
+ Variable j(1);
+ Variable k(2);
+ Variable m(3);
+ Variable n(4);
+ Variables_Set params(k, n);
+
+ Constraint_System cs;
+ cs.insert(i <= m);
+ cs.insert(j <= n);
+ cs.insert(2*i+j <= 2*m+n-k);
+ cs.insert(2*i+j >= 2*m+n-k);
+
+ PIP_Problem pip(cs.space_dimension(), cs.begin(), cs.end(), params);
+
+ bool ok = (pip.solve() == OPTIMIZED_PIP_PROBLEM);
+ if (ok) {
+ const PIP_Tree solution = pip.solution();
+ display_solution(solution, params, Variables_Set(i, j),
+ cs.space_dimension());
+ }
+
+ // Copy constructor is buggy.
+ {
+ PIP_Problem pip_copy = pip;
+ // Here we call the destructor of pip_copy
+ // and we also destroy the (shared) solution tree of pip.
+ }
+
+ return ok;
+}
+
} // namespace
BEGIN_MAIN
DO_TEST(test01);
DO_TEST(test02);
DO_TEST(test03);
+ // Uncomment this to get a segmentation fault.
+ // DO_TEST(test04);
END_MAIN
More information about the PPL-devel
mailing list