2

以下のこのコードを見てください。

#include <windows.h>

void Write(char *pBuffer)
{
//  pBuffer -= 4*sizeof(int);
    for(int i = 0; i<20; i++)
        *(pBuffer + sizeof(int)*i) = i+1;
}

void main()
{
    HANDLE hFile = ::CreateFile("file", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if(INVALID_HANDLE_VALUE == hFile)
    {
        ::MessageBox(NULL, "", "Error", 0);
        return;
    }

    HANDLE hMMF = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 32, NULL);

    char *pBuffer = (char*)::MapViewOfFile(hMMF, FILE_MAP_WRITE, 0, 0, 0);

    Write(pBuffer);

    ::FlushViewOfFile(pBuffer, 100);

    ::UnmapViewOfFile(pBuffer);
}

32 バイトしか割り当てていませんが、割り当てられたサイズを超えて書き込もうとしても、エラーはまったく発生しません。これは仕様によるものですか、それとも Windows コードのバグですか? ただし、コメント部分を含めると、予想どおりエラーが発生します。

私はこの「機能」を有利に利用しようと考えているので、これを尋ねます。できますか?参考までに、私は Win XP バージョン 2002 SP 3 を持っていますが、これは新しい Windows で「修正」されていると思われ、コード IDK が失敗する可能性があります。これの内部を説明する便利なリンクは本当に役に立ちます。

ありがとう

4

2 に答える 2

2

これは、ヒープに割り当てられたバッファーの末尾を超えて書き込む場合と何ら変わりはありません。オペレーティング システムは、マップされていない仮想メモリに書き込む場合にのみ指を叩くことができます。マッピングはページ ベースで、1 ページは 4096 バイトです。kaboom を取得するには、このページを超えて書き込む必要があります。for ループを (4096+4)/4 で終了するように変更して再現します。

于 2011-03-20T18:29:20.630 に答える
0

仮想メモリ マネージャはページごとにメモリをマップする必要があるため、実際にはエクステントは最も近い 4kB (またはシステム ページ サイズが何であれ) に切り上げられます。

マッピングされたデータと同じページへの書き込みが、マッピングの最後を超えてファイルにコミットされるかどうかは文書化されていないと思います。したがって、その動作に依存しないでください。Windows のバージョン間で簡単に変更される可能性があります。

于 2011-03-20T18:28:42.757 に答える