我讀大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
也比每次文件的大小要小)。
矢量大小是84? – 4pie0
嘗試捕捉異常?這可能有助於 – 4pie0
我希望我可以減少你的評論,@piotruś。無論如何,它可能會有助於驗證您的指針是否被爆炸,可能是通過保存其初始值並用'assert'測試它。VS並不總是對「當前值」翻轉有幫助。雖然不一定是這個問題,但你似乎有一個潛在的緩衝區溢出:調用「getBytes」的循環沒有考慮將通過當前位置檢查的字節數(換句話說,可以允許「getBytes」讀取緩衝區的末尾)。 – paddy