[Insight-developers] Small modification to ImportImageContainer
Tom Vercauteren
tom.vercauteren at m4x.org
Tue Mar 31 10:50:15 EDT 2009
Luis,
Rechecking the code, it seems that the current deallocate function
really needs more work...
At first I wanted to mimic AllocateElements:
- AllocateElements does not directly allocate m_ImportPointer but
rather returns a new pointer.
- This new pointer gets in turn assigned to m_ImportPointer by the
calling function.
- Since AllocateElements does not depend on any class member, it can
be made const.
The issues with the current implementation is that:
- It internally checks whether m_ContainerManageMemory is true.
- m_ContainerManageMemory is used to give information about the
argument of DeallocateElements
I see at least two ways of making it cleaner. Both involve changing
"virtual void DeallocateElements (const TElement* ptr) const;"
1) - Use "virtual void DeallocateElements(TElement* ptr,
TElementIdentifier ptrcapacity) const;"
- Move the "if (m_MemoryAllocatedByAllocator)" out of the
DeallocateElements functions.
- Note that the const is removed from the arguments to please vs6
and ease the job for an std::allocator.
2) - Use "virtual void DeallocateManagedMemory();"
- The "if (m_MemoryAllocatedByAllocator)" would be kept within
this function
- This function could also potentially set m_Size and m_Capacity
I have put an example inheriting class using the second option below.
It needs some polishing but should make things clearer.
Tom
template<class TElementIdentifier, typename TElement>
class TestImportImageContainer : public itk::ImportImageContainer<
TElementIdentifier, TElement >
{
public:
/** Standard class typedefs. */
typedef TestImportImageContainer Self;
typedef itk::ImportImageContainer< TElementIdentifier, TElement > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(TestImportImageContainer);
/** Run-time type information (and related methods). */
itkTypeMacro(TestImportImageContainer, ImportImageContainer);
typedef typename Superclass::ElementIdentifier ElementIdentifier;
typedef typename Superclass::Element Element;
typedef std::allocator<TElement> Allocator;
// Methods from itkObject
virtual ~TestImportImageContainer()
{
itkTotalMemoryUsed -= m_TotalSize;
m_TotalSize = 0;
DeallocateManagedMemory();
}
TestImportImageContainer()
: m_TotalSize(0)
,m_MemoryAllocatedByAllocator(false)
{
}
protected:
TElement* AllocateElements(ElementIdentifier size) const
{
std::cout << "ImportImageContainer: Allocating "
<< size << " elements of type "
<< typeid(TElement).name() << " totaling "
<< sizeof(TElement) * size << " bytes" << std::endl;
TElement* data;
try
{
data = m_Allocator.allocate(size);
if (data)
{
new (data) Element[size];
}
}
catch(...)
{
data = 0;
}
if(!data)
{
// We cannot construct an error string here because we may be out
// of memory. Do not use the exception macro.
throw itk::MemoryAllocationError(__FILE__, __LINE__,
"Failed to allocate memory for image.",
ITK_LOCATION);
}
m_TotalSize = size * sizeof(TElement);
itkTotalMemoryUsed += m_TotalSize;
m_MemoryAllocatedByAllocator = true;
std::cout << "ImportImageContainer: Total memory used is "
<< itkTotalMemoryUsed << " bytes" << std::endl;
return data;
}
void DeallocateManagedMemory()
{
std::cout << "ImportImageContainer: Deallocating "
<< this->Capacity() << " elements of type "
<< typeid(TElement).name() << " totaling "
<< sizeof(TElement) * this->Capacity() << " bytes" << std::endl;
if (m_MemoryAllocatedByAllocator)
{
TElement * ptr = this->GetImportPointer();
const TElement * const end = ptr + this->Capacity();
for (TElement * base = ptr; base<end; ++base)
{
m_Allocator.destroy(base);
}
m_Allocator.deallocate(ptr, this->Capacity() );
m_MemoryAllocatedByAllocator = false;
}
else
{
Superclass::DeallocateManagedMemory();
}
}
private:
TestImportImageContainer(const TestImportImageContainer&);
void operator=(const TestImportImageContainer&);
mutable TElementIdentifier m_TotalSize;
mutable Allocator m_Allocator;
mutable bool m_MemoryAllocatedByAllocator;
};
On Tue, Mar 31, 2009 at 15:18, Tom Vercauteren <tom.vercauteren at m4x.org> wrote:
> Hi Luis,
>
>> After looking closer at this two methods I see now why they can
>> both be const: They do not affect member variables (at least in
>> an obvious direct manner). This is still a bit deceptive, because
>> when DeallocateElements() is called, we pass a member variable as
>> its argument..., something that is also strange.... why is that
>> we simply not have the method without arguments, and internally
>> we access in it the member variable ?
>
> We could do that, I just thought that passing the pointer as an
> argument was more generic.
>
>
>> It seems however that the argument of DeallocateElements can
>> be made non-const, and in that way you won't need to cast const
>> away.
>
> I chose to make it const since it was standard compliant and seemed
> more appropriate. The fact that we need the const-cast for vs6 makes
> it however much less elegant...
>
>
>> Do you need this pointer argument to be const in the context
>> in which you will use this method in the derived class that you
>> are developing ?
>
> I should try without it, but I don't think it will really matter for
> my application.
>
>
>> I guess that we may understand better if you post the derived
>> class that you are implementing.
>
> It's a bit complex to post my Image subclass here as it uses some
> internal non-ITK code.
> It basically uses std::allocator<TElement> instead of calling new and delete.
>
> If you find it useful, I could try to modify TestImportImageContainer
> in itkFactoryTestLib so as to use such a custom allocator:
> http://www.itk.org/cgi-bin/viewcvs.cgi/Testing/Code/Common/itkFactoryTestLib.cxx?root=Insight&sortby=date&view=markup
>
>
>> The ImportImageContainer class is at the very heart of ITK so we
>> should be very careful with any changes we made to it. :-/
>
> I most certainly understand that care should be taken for this class!
> This is why I asked for feedback.
>
> Tom
>
More information about the Insight-developers
mailing list