Access violation using LocalAlloc()

Posted by PaulH on Stack Overflow See other posts from Stack Overflow or by PaulH
Published on 2010-05-10T22:15:50Z Indexed on 2010/05/10 22:24 UTC
Read the original article Hit count: 262

I have a Visual Studio 2008 Windows Mobile 6 C++ application that is using an API that requires the use of LocalAlloc(). To make my life easier, I created an implementation of a standard allocator that uses LocalAlloc() internally:

/// Standard library allocator implementation using LocalAlloc and LocalReAlloc 
/// to create a dynamically-sized array. 
/// Memory allocated by this allocator is never deallocated. That is up to the
/// user.
template< class T, int max_allocations > 
class LocalAllocator
{
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; };

    LocalAllocator() throw() : c_( NULL )
    {
    };

    /// Attempt to allocate a block of storage with enough space for n elements
    /// of type T. n>=1 && n<=max_allocations.
    /// If memory cannot be allocated, a std::bad_alloc() exception is thrown.
    pointer allocate( size_type n, const void* /*hint*/ = 0 )
    {
        if( NULL == c_ )
        {   
            c_ = LocalAlloc( LPTR, sizeof( T ) * n );
        }
        else
        {
            HLOCAL c = LocalReAlloc( c_, sizeof( T ) * n, LHND );
            if( NULL == c )
                LocalFree( c_ );
            c_ = c;
        }
        if( NULL == c_ )
            throw std::bad_alloc();
        return reinterpret_cast< T* >( c_ );
    };

    /// Normally, this would release a block of previously allocated storage.
    /// Since that's not what we want, this function does nothing.
    void deallocate( pointer /*p*/, size_type /*n*/ )
    {
        // no deallocation is performed. that is up to the user.
    };

    /// maximum number of elements that can be allocated
    size_type max_size() const throw() { return max_allocations; };

private:
    /// current allocation point
    HLOCAL c_;
}; // class LocalAllocator

My application is using that allocator implementation in a std::vector<>

#define MAX_DIRECTORY_LISTING 512

std::vector< WIN32_FIND_DATA, 
    LocalAllocator< WIN32_FIND_DATA, MAX_DIRECTORY_LISTING > > file_list;

WIN32_FIND_DATA find_data = { 0 };
HANDLE find_file = ::FindFirstFile( folder.c_str(), &find_data );
if( NULL != find_file )
{
    do 
    {
        // access violation here on the 257th item.
        file_list.push_back( find_data );
    } while ( ::FindNextFile( find_file, &find_data ) );

    ::FindClose( find_file );
}

// data submitted to the API that requires LocalAlloc()'d array of WIN32_FIND_DATA structures
SubmitData( &file_list.front() );

On the 257th item added to the vector<>, the application crashes with an access violation:

Data Abort: Thread=8e1b0400 Proc=8031c1b0 'rapiclnt'
AKY=00008001 PC=03f9e3c8(coredll.dll+0x000543c8) RA=03f9ff04(coredll.dll+0x00055f04) BVA=21ae0020 FSR=00000007
First-chance exception at 0x03f9e3c8 in rapiclnt.exe: 0xC0000005: Access violation reading location 0x01ae0020.

LocalAllocator::allocate is called with an n=512 and LocalReAlloc() succeeds. The actual Access Violation exception occurs within the std::vector<> code after the LocalAllocator::allocate call:

     0x03f9e3c8    
     0x03f9ff04    
>    MyLib.dll!stlp_std::priv::__copy_trivial(const void* __first = 0x01ae0020, const void* __last = 0x01b03020, void* __result = 0x01b10020) Line: 224, Byte Offsets: 0x3c    C++
     MyLib.dll!stlp_std::vector<_WIN32_FIND_DATAW,LocalAllocator<_WIN32_FIND_DATAW,512> >::_M_insert_overflow(_WIN32_FIND_DATAW* __pos = 0x01b03020, _WIN32_FIND_DATAW& __x = {...}, stlp_std::__true_type& __formal = {...}, unsigned int __fill_len = 1, bool __atend = true) Line: 112, Byte Offsets: 0x5c    C++
     MyLib.dll!stlp_std::vector<_WIN32_FIND_DATAW,LocalAllocator<_WIN32_FIND_DATAW,512> >::push_back(_WIN32_FIND_DATAW& __x = {...}) Line: 388, Byte Offsets: 0xa0    C++
     MyLib.dll!Foo(unsigned long int cbInput = 16, unsigned char* pInput = 0x01a45620, unsigned long int* pcbOutput = 0x1dabfbbc, unsigned char** ppOutput = 0x1dabfbc0, IRAPIStream* __formal = 0x00000000) Line: 66, Byte Offsets: 0x1e4    C++

If anybody can point out what I may be doing wrong, I would appreciate it.

Thanks, PaulH

© Stack Overflow or respective owner

Related posts about c++

Related posts about windows-mobile