Conversation
Twelve classes held a heap object by raw pointer and freed it with an explicit delete in their destructor. Hold each in a std::unique_ptr instead, so ownership is expressed in the type and the destructors stop hand-managing memory. Eight graph classes own boost::unordered_object_pool instances: utility::graph::Graph and Digraph (element pool plus edge pool each), EnergyGraph, MinimizationGraph, TenANeighborGraph, BuriedUnsatPenaltyGraph, JobDigraph and SewGraph. In Graph and Digraph this also corrects the teardown order: the explicit delete freed the element pool from the destructor body while edge_list_ -- which holds a reference to that pool and returns its elements to it as it is destroyed -- was still alive. Member destruction now runs the list first and frees the pool afterwards. SICFast, MotifHashRigidScore, triangleIterator and FragmentCandidate each owned a single object while leaving their copy operations implicit, so copying any of them would have double-freed. The unique_ptr members make them non-copyable. MotifHashRigidScore::ssinfo1_ and ssinfo2_ were never allocated -- always null, with their only readers commented out -- so they are deleted rather than converted, along with the now-unused SS_Info2 includes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Twelve classes held a heap object by raw pointer and freed it with an explicit
deletein their destructor. This holds each in astd::unique_ptrinstead, so ownership is expressed in the type and the destructors stop hand-managing memory.Graph edge pools (8 classes)
These all own one or two
boost::unordered_object_poolinstances with exactly the same idiom — allocate in the constructor initializer list,deleteand null out in the destructor:utility::graph::Graphedge_list_element_pool_,edge_pool_utility::graph::Digraphedge_list_element_pool_,edge_pool_core::scoring::EnergyGraphenergy_edge_pool_core::scoring::MinimizationGraphminimization_edge_pool_core::scoring::TenANeighborGraphtenA_edge_pool_BuriedUnsatPenaltyGraphbunsat_edge_pool_protocols::jd3::JobDigraphjob_edge_pool_protocols::legacy_sewing::SewGraphhash_edge_pool_In
GraphandDigraphthis also corrects the teardown order. The explicitdeletefreed the element pool from the destructor body, whileedge_list_— which holds a reference to that pool and returns its elements to it as it is destroyed — was still alive. It only worked becausedelete_everything()empties the list first. Member destruction now runs the list first and frees the pool afterwards, so the ordering is guaranteed by declaration order rather than by that coincidence; the declaration order dependency is noted in a comment on the member.The pools are constructed the same way as before (
newin the initializer list), so the constructors are unchanged, and the pools are not serialized (already markedEXEMPTin the cereal save/load), so serialization is unaffected.Single owned objects (4 classes)
SICFast(h1_,h2_),MotifHashRigidScore(reshash_),protocols::viewer::triangleIterator(gradPtr) andFragmentCandidate(pool_name_) each owned a single object while leaving their copy constructor and copy assignment implicit — copying any of them would have duplicated the pointer and double-freed it. Theunique_ptrmembers make them non-copyable, so that hazard is now a compile error rather than a latent crash. Nothing in the tree copies them; the debug build is clean.triangleIterator::densityPtris a non-owning observer pointer and is deliberately left as a raw pointer.MotifHashRigidScore::ssinfo1_andssinfo2_were never allocated — initialized to null, never assigned, and their only readers are commented-out lines — so they are deleted rather than converted, along with the now-unusedSS_Info2includes.Deliberately not included
Three other families of manual
deletein destructors were left out because their fix shape and risk profile genuinely differ from aunique_ptrswap:delete[]array owners (packstat::Array2D,ReplicaExchangeMC,BiasEnergy::Histogram, the MPI pool buffers) needstd::vector, notunique_ptr, and several sit behind MPI build guards.EdgeList/DirectedEdgeList::end_, the sentinel node of the intrusive circular edge list. Copy is already deleted on those classes so there is no bug, and converting would add.get()at roughly 58 use sites in a hot data structure for no correctness gain.InteractionGraphBase::ig_nodes_,AdditionalBackgroundNodesInteractionGraph::bg_nodes_,DoubleLazyEdge::two_body_energies_), which hand out rawNodeBase*/FArray2D*through their public APIs and would need a much wider change.This keeps the diff at ~110 lines rather than the usual larger bundle; the remaining candidates are better as separate PRs than mixed in here.