2014-01-29 4 views
1

Я прочитал большой 5GB файл так:C++ Могут ли отображаемые файлы памяти (boost :: interprocess) перемещаться во время выполнения программы?

элементов данных класса:

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) 

Constructor:

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); 
    } 
} 

Различных класс для обработки каждого сообщения (длиной 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; 
} 

Теперь, если вы внимательно посмотрите на этот код - он отлично работает. Однако, после того, как говорят 500 МБ или 1 Гб, я внезапно получил ошибку, сброшенную на while (pos < last_pos). Когда выбрано исключение и Visual studio позволяет мне отлаживать экземпляр VS, когда я наводил на переменные last_pos и rawbytes VS, они не могут быть прочитаны, но memory для pos может ???? Как будто основной файл с отображением памяти изменил местоположение на полпути через обработку.

NB: У меня определенно не закончилось ОЗУ. Какие-либо предложения?

Сообщение об ошибке:

Необработанное исключение в 0x000000013F86A05C в myprogram.exe: 0xC0000005: Нарушение прав доступа чтения местоположение 0x0000000527533000.

  • когда я парить над rawbytes он говорит значение: 0x0000000000000000
  • pos имеет значение 3825504
  • Оригинальный размер файла, raw_bytes_size был изначально: 2554061585

стека вызовов остановлен на уровне B::getBytes()

UPDATE: Если я запускаю это несколько раз, каждый раз, когда я получаю исключение, значение 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