From 72b356d3097b2c6ca303f34a9909b3b9d3c00a18 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Fri, 10 Mar 2023 11:30:07 +0100 Subject: [PATCH] Add reserve before the creation of a new attribute, copy of an old one: solve a bug for the index version of CMap/GMap when the underlying vector is reallocated --- .../internal/Combinatorial_map_group_functors.h | 9 +++++++++ .../internal/Generalized_map_group_functors.h | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map/internal/Combinatorial_map_group_functors.h b/Combinatorial_map/include/CGAL/Combinatorial_map/internal/Combinatorial_map_group_functors.h index 1db4ec2cbda..06f3c4f4dc3 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map/internal/Combinatorial_map_group_functors.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map/internal/Combinatorial_map_group_functors.h @@ -566,6 +566,15 @@ void test_split_attribute_functor_one_dart Attribute_descriptor_i a1 = amap.template attribute(adart); if ( found_attributes.is_defined(a1) ) { // Here the attribute was already present in the hash_map + + // We need to call reserve for the cc with index case. Indeed, if the vector + // is reallocated, the reference returned by get_attribute(a1) will be + // invalidated, and the copy will be wrong. Note that there is no overhead + // since the creation of the attribute need one allocation. + amap.template attributes().reserve(amap.template attributes().size()+1); + + // Now we are sure that the creation of a new attribute will not imply + // a realloc. Attribute_descriptor_i a2 = amap.template create_attribute(amap.template get_attribute(a1)); diff --git a/Generalized_map/include/CGAL/Generalized_map/internal/Generalized_map_group_functors.h b/Generalized_map/include/CGAL/Generalized_map/internal/Generalized_map_group_functors.h index cbde9898096..4a15c8ea733 100644 --- a/Generalized_map/include/CGAL/Generalized_map/internal/Generalized_map_group_functors.h +++ b/Generalized_map/include/CGAL/Generalized_map/internal/Generalized_map_group_functors.h @@ -293,6 +293,13 @@ void GMap_test_split_attribute_functor_one_dart Attribute_descriptor_i a1 = amap.template attribute(adart); if ( found_attributes.is_defined(a1) ) { // Here the attribute was already present in the hash_map + + // We need to call reserve for the cc with index case. Indeed, if the vector + // is reallocated, the reference returned by get_attribute(a1) will be + // invalidated, and the copy will be wrong. Note that there is no overhead + // since the creation of the attribute need one allocation. + amap.template attributes().reserve(amap.template attributes().size()+1); + Attribute_descriptor_i a2 = amap.template create_attribute(amap.template get_attribute(a1));