2012-04-26 21 views
0

全部,使用MapViewOfFile,指針最終走出內存空間

我正在使用MapViewOfFile在內存中保存文件的一部分。有一個流指向這個文件並寫入它,然後倒帶。我使用指向映射文件開始處的指針,並讀取,直到找到作爲最終字符寫入的空字符。

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()被調用。這會向流寫入一個空值,然後刷新,然後倒回流。然後,我從映射內存的開始處開始讀取字符,直到達到空值。

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確定的那樣,流不會被倒回,並最終填滿分配的空間。

由於流指向底層文件,所以最初不會引起問題。但是,當我試圖走內存時,我從來沒有找到null。這導致了SIGSEV。如果你想知道爲什麼我需要這個的更多細節,see here

爲什麼我不按預期重用內存空間?

+0

你想達到什麼目的?爲什麼代碼不能取消映射視圖並關閉句柄? – 0xC0000022L 2012-04-26 18:50:54

+0

@STATUS_ACCESS_DENIED這只是代碼庫的一個片段,在我完成使用映射空間後,我將其取消映射並關閉句柄。重點是將文件流重定向到Windows系統的內存中。 – 2012-04-26 19:02:36

回答

0

那麼,在這個工作一段時間後,我有一個工作解決方案。我不知道爲什麼這會成功,所以如果有人想出更好的東西,我會很樂意接受他們的回答。

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

正如你看到的,唯一的變化是從申報到409616384大小。爲什麼這個工作時,總字符輸入一次不超過1200,我不知道。如果有人能提供這方面的細節,我將不勝感激。

3

我認爲從MSDN文檔CreateFileMapping這行可能是線索。

映射文件和通過使用輸入和輸出(I/O)函數(ReadFile和WriteFile)訪問的文件不一定是連貫的。

你並不明顯使用Read/WriteFile,但應該根據映射視圖和顯式I/O調用來理解文檔。無論如何,C RTL肯定是使用Win32 API實現的。

總之,這種方法存在問題。

我不知道爲什麼改變視圖/文件大小有幫助;也許它只是將未定義的行爲轉向有益的方向。

+0

我很擔心這一點。在這一點上,這件事情起作用了,我已經沒時間跟蹤這件事了。直到它跳起來,咬人,mngmt。希望我繼續前進。當然,除非有人提出解決方案...... – 2012-04-27 12:27:37

0

當你完成地圖的操作後,只需將其取消映射即可。

UnmapViewOfFile(bp);