2014-01-29 36 views
1

我讀大5GB文件是這樣的:通過映射文件C++內存映射文件(boost :: interprocess)可以在程序執行期間移動嗎?

FileReader::FileReader(const char* FilePath, unsigned long long file_offset_pos){ 
    fm = new file_mapping(FilePath, boost::interprocess::read_only); 
    region = new mapped_region(*fm, boost::interprocess::read_only); 
    raw_bytes_size = region->get_size(); 
    raw_bytes = static_cast<char*>(region->get_address()); 
    file_offset = file_offset_pos; 
    Iterate(raw_bytes, raw_bytes_size); 
} 

迭代:

void FileReader::Iterate(char* rawbytes, unsigned long long size){ 
    unsigned long long i = file_offset; 
    while(i < size){ 
     std::vector<char> order_bytes = co->getBytes(rawbytes, i); 
    } 
} 

甲不同

類的數據成員:

char* raw_bytes; 
unsigned long long raw_bytes_size; 
file_mapping* fm; 
mapped_region* region; 
unsigned long long file_offset; 
MyClass co; (not including details of this as irrelevant) 

構造類來處理每個消息(84字節長):

std::vector<char> B::getBytes(char* rawbytes, unsigned long long& pos){ 
    std::vector<char> bytes; 

    int message_length = 84; 
    unsigned long long last_pos = pos + message_length; 

    bytes.reserve(message_length); 
    while (pos < last_pos){      
     bytes.push_back(rawbytes[pos]); //The exception occurs here 
     pos++; 
    } 

    return bytes; 
} 

現在,如果仔細看一下這段代碼,它可以正常工作。然而,在說500MB或1GB後,我突然發現錯誤while (pos < last_pos)。當拋出異常並且Visual Studio允許我在VS的一個實例中進行調試時,當我將鼠標懸停在變量last_pos上,並且rawbytes VS說他們不能被讀取,但memory爲pos可以嗎?就好像底層存儲器映射文件在處理過程中途改變了位置。

注:我絕對沒有用完RAM。有什麼建議麼?

的錯誤信息是:

在0x000000013F86A05C未處理異常MyProgram.exe: 0000005:訪問衝突讀取位置0x0000000527533000。

  • 當我將鼠標懸停在rawbytes它說值:0x0000000000000000
  • pos具有價值3825504
  • 文件的原始大小,raw_bytes_size最初是:2554061585

調用堆棧停在B::getBytes()

更新:如果我運行這幾次,每次我得到異常值pos(讀取下一條消息的位置標記)是不同的....所以它不是因爲我已經覆蓋文件(加pos也比每次文件的大小要小)。

+0

矢量大小是84? – 4pie0

+0

嘗試捕捉異常?這可能有助於 – 4pie0

+0

我希望我可以減少你的評論,@piotruś。無論如何,它可能會有助於驗證您的指針是否被爆炸,可能是通過保存其初始值並用'assert'測試它。VS並不總是對「當前值」翻轉有幫助。雖然不一定是這個問題,但你似乎有一個潛在的緩衝區溢出:調用「getBytes」的循環沒有考慮將通過當前位置檢查的字節數(換句話說,可以允許「getBytes」讀取緩衝區的末尾)。 – paddy

回答

0

不,mmap不會自發地移動(但不需要在重映射中的相同地址)。

嘗試

if (size>=84) 
{ 
    while(i < (size-84)) 
    { 
     std::vector<char> order_bytes = co->getBytes(rawbytes, i); 
    } 
} 

爲了解釋(不是不可能?)之際,該文件不是在映射時的84的倍數。

+0

但pos(實質上是一個位置標記)遠小於文件的大小。 – user997112

+0

我認爲你需要檢查這個假設。如果這不是問題,那麼就會比修改指針的「簡單」內存損壞/ [UB](http://en.wikipedia.org/wiki/Undefined_behavior)...(可能是文件被重寫/打開後截斷?) – sehe