0

全て、

MapViewOfFileを使用して、ファイルの一部をメモリに保持しています。このファイルをポイントして書き込み、次に巻き戻されるストリームがあります。マップされたファイルの先頭へのポインターを使用し、最後の文字として書き込んだnull文字に到達するまで読み取ります。

int fd;
yyout = tmpfile();
fd = fileno(yyout);
#ifdef WIN32
    HANDLE fm;
    HANDLE h = (HANDLE) _get_osfhandle (fd);

    fm = CreateFileMapping(
             h,
             NULL,
             PAGE_READWRITE|SEC_RESERVE,
             0,
             4096,
             NULL);
    if (fm == NULL) { 
            fprintf (stderr, "%s: Couldn't access memory space! %s\n", argv[0],  strerror (GetLastError()));
            exit(GetLastError());
    }
    bp = (char*)MapViewOfFile(
              fm,
              FILE_MAP_ALL_ACCESS,
              0,
              0,
              0);
    if (bp == NULL) { 
            fprintf (stderr, "%s: Couldn't fill memory space! %s\n", argv[0],  strerror (GetLastError()));
            exit(GetLastError());
    }

が呼び出されるyyoutまで、データはストリームに送信されます。flushData()これにより、ストリームにnullが書き込まれ、フラッシュされてから、ストリームが巻き戻されます。次に、マップされたメモリの先頭から開始し、nullになるまでcharsを読み取ります。

void flushData(void) {
    /* write out data in the stream and reset */ 
    fprintf(yyout, "%c%c%c", 13, 10, '\0');
    fflush(yyout);
    rewind(yyout);
    if (faqLine == 1) {
        faqLine = 0; /* don't print faq's to the data file */
    }
    else {
        char * ps = bp;
        while (*ps != '\0') {
                fprintf(outstream, "%c%c", *ps, blank);
                ps++;
            }
        fflush(outfile);
    }
    fflush(yyout);
    rewind(yyout);
}

フラッシュ後、より多くのデータがストリームに書き込まれます。これは、メモリ領域の先頭に設定する必要があります。gdbで判断できる限り、ストリームは巻き戻されず、最終的に割り当てられたスペースがいっぱいになります。

ストリームは基になるファイルを指しているため、これによって最初は問題が発生することはありません。しかし、私が記憶を歩こうとすると、私は決してヌルを見つけません。これはにつながりSIGSEVます。私がこれを必要とする理由の詳細が必要な場合は、こちらを参照してください

なぜメモリスペースを期待どおりに再利用しないのですか?

4

3 に答える 3

4

CreateFileMapping の MSDN ドキュメントのこの行が手がかりになると思います。

マップされたファイルと、入出力 (I/O) 関数 (ReadFile および WriteFile) を使用してアクセスされるファイルは、必ずしも一貫性があるとは限りません。

明らかに Read/WriteFile を使用していませんが、ドキュメントは、マップされたビューと明示的な I/O 呼び出しの観点から理解する必要があります。いずれにせよ、C RTL は確実に Win32 API を使用して実装されています。

要するに、このアプローチには問題があります。

ビュー/ファイルサイズを変更すると役立つ理由がわかりません。おそらくそれは、未定義の動作をたまたま有益な方向にシフトするだけです。

于 2012-04-26T23:26:13.120 に答える
0

さて、しばらくこれに取り組んだ後、私は実用的な解決策を持っています。これが成功する理由がわからないので、誰かがより良いものを思いついた場合は、代わりに喜んでその答えを受け入れます.

fm = CreateFileMapping(
         h,
         NULL,
         PAGE_READWRITE|SEC_RESERVE,
         0,
         16384,
         NULL);

ご覧のとおり、唯一の変更は宣言されたサイズ from から4096to16384です。一度に入力される合計文字数が 1200 以下の場合にこれが機能する理由はわかりません。誰かがこれについて詳細を提供できれば、私はそれを感謝します.

于 2012-04-26T20:09:42.340 に答える