From 31c898ba11d3d9d209f21ae64e952dfea4082f44 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Tue, 13 Jan 2026 13:53:02 +0100 Subject: [PATCH] [hist] Delete `TMultiGraph::Add(TMultiGraph*, Option_t*)` overload The `TMultiGraph::Add(TMultiGraph*, Option_t*)` overload that adds the graphs in another **TMultiGraph** to a **TMultiGraph** is removed without deprecation. It was inconsistent from a memory ownership standpoint. A **TMultiGraph** always owns all the added graphs, so adding the same graph instances to two **TMultiGraphs** forcibly led to double-deletes. No deprecation period is defined, because as the overload unavoidibly leads to double-deletes, it is likely not used. Or at least rarely used, because it can work if one of the two TMultiGraphs is leaked on purpose. If you want to add all graphs from `otherMultiGraph` to `multiGraph`, one should use a for-loop and clone the graphs instead: ```c++ for (TObject *gr : *otherMultiGraph) { multiGraph->Add(static_cast(gr->Clone())); } ``` Some examle code with the double-delete: ```c++ { auto mg1 = new TMultiGraph(); auto mg2 = new TMultiGraph(); auto gr1 = new TGraph(); mg1->Add(gr1); auto gr2 = new TGraph(); mg1->Add(gr2); mg2->Add(mg1); // This is the Add(TMultiGraph* overload) delete mg1; delete mg2; } ``` --- README/ReleaseNotes/v640/index.md | 9 +++++++++ hist/hist/inc/TMultiGraph.h | 1 - hist/hist/src/TMultiGraph.cxx | 26 -------------------------- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/README/ReleaseNotes/v640/index.md b/README/ReleaseNotes/v640/index.md index 16d296b510785..433e1bd6124b6 100644 --- a/README/ReleaseNotes/v640/index.md +++ b/README/ReleaseNotes/v640/index.md @@ -44,6 +44,15 @@ The following people have contributed to this new version: * The `TGLIncludes.h` and `TGLWSIncludes.h` that were deprecated in ROOT 6.38 and scheduled for removal are gone now. Please include your required headers like `` or `` directly. * The GLEW headers (`GL/eglew.h`, `GL/glew.h`, `GL/glxew.h`, and `GL/wglew.h`) that were installed when building ROOT with `builtin_glew=ON` are no longer installed. This is done because ROOT is moving away from GLEW for loading OpenGL extensions. * The `TF1`, `TF2`, and `TF3` constructors for CINT compatibility were removed. This concerns the templated constructors that additionally took the name of the used functor class and member function. With ROOT 6, these names can be omitted. +* The `TMultiGraph::Add(TMultiGraph*, Option_t*)` overload that adds the graphs in another **TMultiGraph** to a **TMultiGraph** is removed without deprecation. + It was inconsistent from a memory ownership standpoint. + A **TMultiGraph** always owns all the added graphs, so adding the same graph instances to two **TMultiGraphs** forcibly led to double-deletes. + If you want to add all graphs from `otherMultiGraph` to `multiGraph`, please use a for-loop and clone the graphs instead: + ```c++ + for (TObject *gr : *otherMultiGraph) { + multiGraph->Add(static_cast(gr->Clone())); + } + ``` ## Build System diff --git a/hist/hist/inc/TMultiGraph.h b/hist/hist/inc/TMultiGraph.h index 3afb3cbf93d73..3767235c120ef 100644 --- a/hist/hist/inc/TMultiGraph.h +++ b/hist/hist/inc/TMultiGraph.h @@ -49,7 +49,6 @@ class TMultiGraph : public TNamed { ~TMultiGraph() override; virtual void Add(TGraph *graph, Option_t *chopt = ""); - virtual void Add(TMultiGraph *multigraph, Option_t *chopt = ""); void Browse(TBrowser *b) override; Int_t DistancetoPrimitive(Int_t px, Int_t py) override; void Draw(Option_t *chopt = "") override; diff --git a/hist/hist/src/TMultiGraph.cxx b/hist/hist/src/TMultiGraph.cxx index 16dcc1fb5fcbb..7e8adcd8be26c 100644 --- a/hist/hist/src/TMultiGraph.cxx +++ b/hist/hist/src/TMultiGraph.cxx @@ -422,32 +422,6 @@ void TMultiGraph::Add(TGraph *graph, Option_t *chopt) } -//////////////////////////////////////////////////////////////////////////////// -/// Add all the graphs in "multigraph" to the list of graphs. -/// -/// - If "chopt" is defined all the graphs in "multigraph" will be added with -/// the "chopt" option. -/// - If "chopt" is undefined each graph will be added with the option it had -/// in "multigraph". - -void TMultiGraph::Add(TMultiGraph *multigraph, Option_t *chopt) -{ - TList *graphlist = multigraph->GetListOfGraphs(); - if (!graphlist) return; - - if (!fGraphs) fGraphs = new TList(); - - auto lnk = graphlist->FirstLink(); - - while (lnk) { - auto obj = lnk->GetObject(); - if (!strlen(chopt)) fGraphs->Add(obj,lnk->GetOption()); - else fGraphs->Add(obj,chopt); - lnk = lnk->Next(); - } -} - - //////////////////////////////////////////////////////////////////////////////// /// Browse multigraph.