From 1f4618cad94f362422c552338c6fe83998a5d329 Mon Sep 17 00:00:00 2001 From: sbrandt Date: Mon, 13 Jan 2014 21:56:07 +0000 Subject: Fix for #1363 git-svn-id: http://svn.cactuscode.org/flesh/trunk@5064 17b73243-c579-4c4c-a9d2-2d5706c11dac --- src/piraha/smart_ptr.cc | 2 +- src/piraha/smart_ptr.hpp | 45 ++++++++++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/piraha/smart_ptr.cc b/src/piraha/smart_ptr.cc index 112e0f62..c6600d6f 100644 --- a/src/piraha/smart_ptr.cc +++ b/src/piraha/smart_ptr.cc @@ -2,6 +2,6 @@ namespace cctki_piraha { -std::set *ptrs = new std::set(); +std::set *ptrs = 0; } diff --git a/src/piraha/smart_ptr.hpp b/src/piraha/smart_ptr.hpp index b8784b55..1d9dcf6f 100644 --- a/src/piraha/smart_ptr.hpp +++ b/src/piraha/smart_ptr.hpp @@ -10,34 +10,41 @@ namespace cctki_piraha { +// This global debug variable is used to detect the case +// where the same pointer is accidentally tracked by two +// independent smart_ptr_guts objects. +// +// This can come about if the programmer does this: +// foo *f = new foo(); +// smart_ptr f1(f); +// smart_ptr f2(f); extern std::set *ptrs; -// TODO: This code is disabled because it leads to segfaults during -// startup. Most likely, this code is used during initialisation of -// global variables, but also implicitly assumes that all global -// variables have already been initialised. -#if 0 -//#ifndef NDEBUG -inline void add(std::set& v,void *t) { +#ifndef NDEBUG +inline void add(void *t) { if(t == NULL) return; + if(ptrs == 0) + ptrs = new std::set(); // TODO: Don't separate finding and inserting; do it in one go to // save a lookup. - assert(v.find(t) == v.end()); - v.insert(t); + assert(ptrs->find(t) == ptrs->end()); + ptrs->insert(t); } -inline void remove(std::set& v,void* t) { - // TODO: Don't separate finding and erasing; do it in one go - // to save a lookup. - std::set::iterator it = v.find(t); - assert(it != v.end()); - v.erase(it); +inline void remove(void* t) { + if(t == NULL) + return; + // TODO: Don't separate finding and erasing; do it in one go + // to save a lookup. + std::set::iterator it = ptrs->find(t); + assert(it != ptrs->end()); + ptrs->erase(it); } #else -inline void add(std::set& v,void* t) { +inline void add(void* t) { } -inline void remove(std::set& v,void* t) { +inline void remove(void* t) { } #endif @@ -52,12 +59,12 @@ class smart_ptr_guts { bool array; smart_ptr_guts(int rc,T *p,bool array_) : ref_count(rc), ptr(p), array(array_) { if(ptr != NULL) { - add(*ptrs,(void*)ptr); + add((void*)ptr); } } ~smart_ptr_guts() { if(ptr != NULL) { - remove(*ptrs,(void*)ptr); + remove((void*)ptr); if(array) delete[] ptr; else -- cgit v1.2.3