代码之家  ›  专栏  ›  技术社区  ›  Steven

Windows Mobile上的连续VirtualAlloc行为

  •  2
  • Steven  · 技术社区  · 16 年前

    on Win32 Windows CE .

    // 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
    

    文档,无论是合法的还是巧合的,但我在谷歌上发现了许多期望这种行为的代码示例。

    在Windows CE 5.0/5.2上,如果我使用“c”处的内存块,在99%的情况下没有问题,但在某些(不是全部)Windows Mobile 6设备上, ReadFile ReadFile 正在呼叫 或类似,因此返回false。如果我表演两个 ReadFile

    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
    
    3 回复  |  直到 13 年前
        1
  •  2
  •   Scott Langham    16 年前

        2
  •  2
  •   Scott Langham    16 年前

    我不信任IsBadWritePtr,请看: http://support.microsoft.com/kb/960154 我认为它会尝试写入内存,并查看是否出现硬件异常。它处理异常,然后返回true或false。但是,我听说有些硬件在尝试写入一页或类似内容时只会引发一次异常。

    没有MEM_COMMIT,你就不可能使用VirtualAlloc,所以你只需要保留虚拟内存地址。然后,当你真的想使用内存时,再次调用VirtualAlloc进行提交。由于您已经预订了页面,因此应该能够连续提交它们。

        3
  •  1
  •   Scott Langham    16 年前

    基本上,如果你的VirtualAlloc超过2兆,它就会进入虚拟内存的大内存区域,这会让你超过32兆的限制。

    关于这一切是如何运作的,这里有一个很好的讨论:
    http://msdn.microsoft.com/en-us/library/ms836325.aspx

    我自己在以前的产品上使用过它,它对我来说很有用。

    推荐文章