Skip to content
Snippets Groups Projects
Commit 096d6aba authored by Russell Taylor's avatar Russell Taylor
Browse files

Fix memory leak introduced into SpectraDetectorMap by recent changes. Re #131.

parent 66215f1b
No related merge requests found
......@@ -2,6 +2,7 @@
#define SPECTRADETECTORMAP_
#include "MantidKernel/System.h"
#include "boost/shared_ptr.hpp"
#ifndef HAS_UNORDERED_MAP_H
#include <map>
#else
......@@ -29,7 +30,7 @@ namespace API
@author Laurent C Chapon, ISIS, RAL
@date 29/04/2008
Copyright &copy; 2007-8 STFC Rutherford Appleton Laboratories
Copyright &copy; 2007-8 STFC Rutherford Appleton Laboratory
This file is part of Mantid.
......@@ -76,7 +77,7 @@ public:
/// Get a vector of IDetector contributing to a spectrum
std::vector<Geometry::IDetector*> getDetectors(const int spectrum_number) const;
/// Get a detector object (Detector or DetectorGroup) for the given spectrum number
Geometry::IDetector* getDetector(const int spectrum_number) const;
boost::shared_ptr<Geometry::IDetector> getDetector(const int spectrum_number) const;
private:
///Copy Contructor
......
......@@ -5,6 +5,18 @@
namespace Mantid
{
namespace Kernel
{
/// An object for constructing a shared_ptr that won't ever delete its pointee
struct NullDeleter
{
/// Does nothing
void operator()(void const *) const
{}
};
} // namespace Kernel
namespace API
{
......@@ -86,16 +98,13 @@ std::vector<Geometry::IDetector*> SpectraDetectorMap::getDetectors(const int spe
if (ndets<1)
{
detectors.clear();
// Will just return an empty vector
return detectors;
}
std::pair<smap_it,smap_it> det_range=_s2dmap.equal_range(spectrum_number);
int i=0;
detectors.resize(ndets);
smap_it it;
for (it=det_range.first; it!=det_range.second; ++it)
for (smap_it it=det_range.first; it!=det_range.second; ++it)
{
detectors[i++]=(*it).second;
detectors.push_back(it->second);
}
return detectors;
}
......@@ -107,7 +116,7 @@ std::vector<Geometry::IDetector*> SpectraDetectorMap::getDetectors(const int spe
* the returned object's concrete type will be DetectorGroup.
* @todo Write a test for this method
*/
Geometry::IDetector* SpectraDetectorMap::getDetector(const int spectrum_number) const
boost::shared_ptr<Geometry::IDetector> SpectraDetectorMap::getDetector(const int spectrum_number) const
{
int ndets=ndet(spectrum_number);
if ( ndets == 0 )
......@@ -118,18 +127,13 @@ Geometry::IDetector* SpectraDetectorMap::getDetector(const int spectrum_number)
else if ( ndets == 1)
{
// If only 1 detector for the spectrum number, just return it
return _s2dmap.find(spectrum_number)->second;
// Have to create the shared pointer with a null deleter in this case so that the detector
// doesn't get deleted when the shared pointer goes out of scope
return boost::shared_ptr<IDetector>(_s2dmap.find(spectrum_number)->second, Kernel::NullDeleter());
}
// Else need to construct a DetectorGroup and return that
// @todo MEMORY LEAK ALERT!!!
Geometry::DetectorGroup *group = new Geometry::DetectorGroup(getDetectors(spectrum_number));
// std::pair<smap_it,smap_it> det_range=_s2dmap.equal_range(spectrum_number);
// for (smap_it it=det_range.first; it!=det_range.second; ++it)
// {
// group->addDetector( (*it).second );
// }
return group;
return boost::shared_ptr<IDetector>(new Geometry::DetectorGroup(getDetectors(spectrum_number)));
}
} // Namespace API
......
......@@ -37,7 +37,7 @@ TYPEDEF_HIDES_STRUCT = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_ALL = NO
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
......
......@@ -138,15 +138,15 @@ public:
TS_ASSERT_EQUALS( outputWS->spectraNo(4), 4 )
boost::shared_ptr<SpectraDetectorMap> sdm = outputWS->getSpectraMap();
IDetector *det;
boost::shared_ptr<IDetector> det;
TS_ASSERT_THROWS_NOTHING( det = sdm->getDetector(0) )
TS_ASSERT( dynamic_cast<DetectorGroup*>(det) )
TS_ASSERT( boost::dynamic_pointer_cast<DetectorGroup>(det) )
TS_ASSERT_THROWS_NOTHING( det = sdm->getDetector(1) )
TS_ASSERT( dynamic_cast<Detector*>(det) )
TS_ASSERT( boost::dynamic_pointer_cast<Detector>(det) )
TS_ASSERT_THROWS( sdm->getDetector(2), Exception::NotFoundError )
TS_ASSERT_THROWS( sdm->getDetector(3), Exception::NotFoundError )
TS_ASSERT_THROWS_NOTHING( det = sdm->getDetector(4) )
TS_ASSERT( dynamic_cast<Detector*>(det) )
TS_ASSERT( boost::dynamic_pointer_cast<Detector>(det) )
}
private:
......
......@@ -22,7 +22,7 @@ fi
echo
echo "Compiling the test executable..."
g++ -O0 -g3 -o runner.exe runner.cpp -I ../inc -I ../../API/inc \
g++ -O0 -g3 -o runner.exe runner.cpp -I ../inc -I ../../API/inc -I ../../../Third_Party/include \
-L ../../Debug -L ../../Build -L ../../../Third_Party/lib/linux64 \
-lMantid -lPocoFoundation -lPocoUtil -lPocoXML -lPocoNet -lboost_python \
-lpython2.3 -lboost_regex -lboost_filesystem -lgsl -lgslcblas -lNeXus
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment