Windows Mobileアプリケーションのメモリパフォーマンスを最適化しており、Win32上のVirtualAlloc とWindowsCEの動作にいくつかの違いがあります。
次のテストを検討してください。
// Allocate 64k of memory
BYTE *a = (BYTE*)VirtualAlloc(0, 65536,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
// Allocate a second contiguous 64k of memory
BYTE *b = (BYTE*)VirtualAlloc(a+65536, 65536,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
BYTE *c = a + 65528; // Set a pointer near the end of the first allocation
BOOL valid1 = !IsBadWritePtr(c, 8); // Expect TRUE
BOOL valid2 = !IsBadWritePtr(c+8, 4088); // Expect TRUE
BOOL valid3 = !IsBadWritePtr(c, 4096); // TRUE on Win32, FALSE on WinCE
コードは、「c」で始まる4096のデータを「割り当て」ます。Win32では、これは機能します。VirtualAllocのドキュメントには、それが合法であるか偶然であるかについての言及はありませんが、この動作を期待するGoogleで見つけたコードの例はたくさんあります。
Windows CE 5.0 / 5.2では、「c」でメモリブロックを使用すると、99%の場合問題はありませんが、一部の(すべてではない)Windows Mobile 6デバイスでは、ReadFileとWriteFileがエラー87(パラメータ間違っている。)。ReadFileがIsBadWritePtrまたは同様のものを呼び出していると想定し、これが原因でfalseを返します。2つのReadFile呼び出しを実行すると、すべてが正常に機能します。(もちろん、他のAPI呼び出しも失敗する可能性があります。)
上記を機能させるために、 VirtualAllocによって返されるメモリを拡張する方法を探しています。Windows CEで大量のメモリを予約することは、各プロセスが32MBしか取得できず、他のアイテムがロードされているため、他の問題を引き起こさずに大量のメモリを予約することはできないため、問題があります。(共有領域に大量のメモリを予約することは可能ですが、これには他の問題もあります。)
VirtualAllocに、事前に予約せずにリージョンを拡大または結合させる方法はありますか?
次の例を考えると、問題があるのではないかと思います。
HANDLE hHeap1 = HeapCreate(0, 0, 0); // Heap defaults to 192k
BYTE * a1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +96 bytes from start of heap
BYTE * b1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of a1
BYTE * c1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of b1
BYTE * d1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +4528 bytes from end of c1
HANDLE hHeap2 = HeapCreate(0, 4*1024*1024, 4*1024*1024); // 4MB Heap
BYTE * a2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +96 bytes from start of heap
BYTE * b2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of a2
BYTE * c2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of b2
BYTE * d2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of c2