I have a Visual Studio 2008 C++ project for Windows Mobile 6.x where I need more memory than is available to me in the 32MB process slot. So, I'm looking at using memory mapped files. I've created a standard allocator implementation that replaces new/delete with CreateFileMapping and MapViewOfFile.
The intended use is something like this:
struct Foo
{
    char a[ 1024 ];
};
int _tmain( int argc, _TCHAR* argv[] )
{
    std::vector< boost::shared_ptr< Foo > > v;
    for( int i = 0; i < 40000; ++i )
    {
        v.push_back( boost::allocate_shared< Foo >( MappedFileAllocator< Foo >() ) );
    }
    return 0;
}
With the std::allocator, I can get 28197 iterations in that example before I get a std::bad_alloc exception. With the MappedFileAllocator, I get 32371 iterations before the device completely freezes and has to be rebooted. Since my device has 512MB of RAM, I expected to be able to get far more iterations out of that loop. 
My MappedFileAllocator implementation is:
template< class T >
class MappedFileAllocator
{
public:
    typedef T         value_type;
    typedef size_t    size_type;
    typedef ptrdiff_t difference_type;
    typedef T*        pointer;
    typedef const T*  const_pointer;
    typedef T&        reference;
    typedef const T&  const_reference;
    pointer address( reference r ) const { return &r; };
    const_pointer address( const_reference r ) const { return &r; };
    /// convert a MappedFileAllocator<T> to a MappedFileAllocator<U>
    template< class U >
    struct rebind { typedef MappedFileAllocator< U > other; };
    MappedFileAllocator() throw() : mapped_file_( INVALID_HANDLE_VALUE ) { };
    template< class U >
    explicit MappedFileAllocator( const MappedFileAllocator< U >& other ) throw()
        : mapped_file_( INVALID_HANDLE_VALUE )
    {
        if( other.mapped_file_ != this->mapped_file_ )
        {
            ::DuplicateHandle( GetCurrentProcess(), 
                other.mapped_file_,
                GetCurrentProcess(),
                &this->mapped_file_,
                0,
                FALSE,
                DUPLICATE_SAME_ACCESS );
        }
    };
    pointer allocate( size_type n, const void* /*hint*/ = 0 )
    {
        if( n > max_size() )
           throw std::bad_alloc();
        if( n > 0 )
        {
            size_type buf_size = n * sizeof( value_type );
            mapped_file_ = ::CreateFileMapping( INVALID_HANDLE_VALUE, 
                NULL,
                PAGE_READWRITE,
                0,
                buf_size,
                L"{45E4FA7B-7B1E-4939-8CBB-811276B5D4DE}" );
            if( NULL == mapped_file_ )
                throw std::bad_alloc();
            LPVOID f = ::MapViewOfFile( mapped_file_, 
                FILE_MAP_READ | FILE_MAP_WRITE, 
                0, 
                0, 
                buf_size );
            if( NULL == f )
            {
                ::CloseHandle( mapped_file_ );
                mapped_file_ = INVALID_HANDLE_VALUE;
                throw std::bad_alloc();
            }
            return reinterpret_cast< T* >( f );
        }
        return 0;
    };
    void deallocate( pointer p, size_type n )
    {
        if( NULL != p )
        {
            ::FlushViewOfFile( p, n * sizeof( T ) );
            ::UnmapViewOfFile( p );
        }
        if( INVALID_HANDLE_VALUE != mapped_file_ )
        {
            ::CloseHandle( mapped_file_ );
            mapped_file_ = INVALID_HANDLE_VALUE;
        }
    };
    size_type max_size() const throw() 
    { 
        return std::numeric_limits< size_type >::max() / sizeof( T );
    };
    /// handle to the memory-mapped file
    HANDLE mapped_file_;
private:
    /// disallow assignment
    void operator=( const MappedFileAllocator& );
}; // class MappedFileAllocator
Can anybody suggest where I may be going wrong with my MappedFileAllocator implementation? 
Thanks, PaulH
Check if boost::interprocess supports Windows Mobile. They have facilities for creating memory-mapped files and using the memory to allocate any piece of data you want:
http://www.boost.org/doc/libs/1_47_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.mapped_file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With