Make ConditionedCostFunction compatible with repeated CostFunction.

If the user uses the same conditioner twice, it does not lead
to a double free errors.

https://github.com/ceres-solver/ceres-solver/issues/422

Change-Id: I9041ddcbffa8dcb882a63bddb82b384897efc970
diff --git a/include/ceres/conditioned_cost_function.h b/include/ceres/conditioned_cost_function.h
index e5f5fc4..f92787e 100644
--- a/include/ceres/conditioned_cost_function.h
+++ b/include/ceres/conditioned_cost_function.h
@@ -77,6 +77,8 @@
   // per-residual conditioner. Takes ownership of all of the wrapped cost
   // functions, or not, depending on the ownership parameter. Conditioners
   // may be NULL, in which case the corresponding residual is not modified.
+  //
+  // The conditioners can repeat.
   ConditionedCostFunction(CostFunction* wrapped_cost_function,
                           const std::vector<CostFunction*>& conditioners,
                           Ownership ownership);
diff --git a/internal/ceres/conditioned_cost_function.cc b/internal/ceres/conditioned_cost_function.cc
index 08899e3..d933ad7 100644
--- a/internal/ceres/conditioned_cost_function.cc
+++ b/internal/ceres/conditioned_cost_function.cc
@@ -68,7 +68,7 @@
 
 ConditionedCostFunction::~ConditionedCostFunction() {
   if (ownership_ == TAKE_OWNERSHIP) {
-    STLDeleteElements(&conditioners_);
+    STLDeleteUniqueContainerPointers(conditioners_.begin(), conditioners_.end());
   } else {
     wrapped_cost_function_.release();
   }
diff --git a/internal/ceres/conditioned_cost_function_test.cc b/internal/ceres/conditioned_cost_function_test.cc
index 528e0ee..6297451 100644
--- a/internal/ceres/conditioned_cost_function_test.cc
+++ b/internal/ceres/conditioned_cost_function_test.cc
@@ -67,7 +67,7 @@
 };
 
 // Tests that ConditionedCostFunction does what it's supposed to.
-TEST(CostFunctionTest, ConditionedCostFunction) {
+TEST(ConditionedCostFunction, NormalOperation) {
   double v1[kTestCostFunctionSize], v2[kTestCostFunctionSize],
       jac[kTestCostFunctionSize * kTestCostFunctionSize],
       result[kTestCostFunctionSize];
@@ -92,17 +92,16 @@
     conditioners.push_back(new LinearCostFunction(i + 2, i * 7));
   }
 
-  ConditionedCostFunction conditioned_cost_function(difference_cost_function,
-                                                    conditioners,
-                                                    TAKE_OWNERSHIP);
+  ConditionedCostFunction conditioned_cost_function(
+      difference_cost_function, conditioners, TAKE_OWNERSHIP);
   EXPECT_EQ(difference_cost_function->num_residuals(),
             conditioned_cost_function.num_residuals());
   EXPECT_EQ(difference_cost_function->parameter_block_sizes(),
             conditioned_cost_function.parameter_block_sizes());
 
-  double *parameters[1];
+  double* parameters[1];
   parameters[0] = v1;
-  double *jacs[1];
+  double* jacs[1];
   jacs[0] = jac;
 
   conditioned_cost_function.Evaluate(parameters, result, jacs);
@@ -122,5 +121,21 @@
   }
 }
 
+TEST(ConditionedCostFunction, SharedConditionersDoNotTriggerDoubleFree) {
+  // Make a cost function that computes x - v2
+  double v2[kTestCostFunctionSize];
+  VectorRef v2_vector(v2, kTestCostFunctionSize, 1);
+  Matrix identity = Matrix::Identity(kTestCostFunctionSize, kTestCostFunctionSize);
+  NormalPrior* difference_cost_function = new NormalPrior(identity, v2_vector);
+  CostFunction* conditioner = new LinearCostFunction(2, 7);
+  std::vector<CostFunction*> conditioners;
+  for (int i = 0; i < kTestCostFunctionSize; i++) {
+    conditioners.push_back(conditioner);
+  }
+
+  ConditionedCostFunction conditioned_cost_function(
+      difference_cost_function, conditioners, TAKE_OWNERSHIP);
+}
+
 }  // namespace internal
 }  // namespace ceres