Я работаю с более старым кодом, который размещает часть оперативной памяти и загружает в нее двоичный файл. Двоичный файл представляет собой серию 8-битных плоскостей серого изображения размером X по Y, глубиной по Z. Размер файлов обычно составляет от 500 мегабайт до 10 гигабайт.
Существующий код использует сложное расположение указателей для доступа к отдельным плоскостям в плоскостях XY, XZ или YZ.
Что бы я как сделать, это заменить указатель на один вектор векторов, где каждый подвектор представляет собой плоскость XY в данных. Цель этого состоит в том, чтобы получить некоторую безопасность и проверить, что вы получаете с векторами, а не с необработанным доступом к указателю.
На основании этого предыдущего вопроса ( Можно ли инициализировать std :: вектор над уже выделенной памятью? ) У меня есть следующий код
//preallocate.h
template <typename T>
class PreAllocator
{
private:
T* memory_ptr;
std::size_t memory_size;
public:
typedef std::size_t size_type;
typedef T* pointer;
typedef T value_type;
PreAllocator(T* memory_ptr, std::size_t memory_size) : memory_ptr(memory_ptr), memory_size(memory_size) {}
PreAllocator(const PreAllocator& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};
template<typename U>
PreAllocator(const PreAllocator<U>& other) throw() : memory_ptr(other.memory_ptr), memory_size(other.memory_size) {};
template<typename U>
PreAllocator& operator = (const PreAllocator<U>& other) { return *this; }
PreAllocator<T>& operator = (const PreAllocator& other) { return *this; }
~PreAllocator() {}
pointer allocate(size_type n, const void* hint = 0) {return memory_ptr;}
void deallocate(T* ptr, size_type n) {}
size_type max_size() const {return memory_size;}
};
Упрощенная основная функция выглядит следующим образом:
TOMhead header;
uint8_t* TOMvolume;
size_t volumeBytes = 0;
int main(int argc, char *argv[])
{
std::fstream TOMfile;
std::ios_base::iostate exceptionMask = TOMfile.exceptions() | std::ios::failbit| std::ifstream::badbit;
TOMfile.exceptions(exceptionMask);
try {
TOMfile.open(argv[1],std::ios::in|std::ios::binary);
}
catch (std::system_error& error) {
std::cerr << error.code().message() << std::endl;
return ERROR;
}
TOMfile.read((char*) &header, sizeof(header));
if (!TOMfile)
{
std::cout<<"Error reading file into memory, expected to read " << sizeof(header) << " but only read " << TOMfile.gcount() << "bytes" <<std::endl;
return ERROR;
}
TOMfile.seekg(std::ios_base::beg); // rewind to begining of the file
TOMfile.seekg(sizeof(header)); // seek to data beyond the header
volumeBytes = (header.xsize * header.ysize * header.zsize);
std::cout << "Trying to malloc " << volumeBytes << " bytes of RAM" << std::endl;
TOMvolume = (uint8_t*) malloc(volumeBytes);
if (TOMvolume == NULL)
{
std::cout << "Error allocating RAM for the data" << std::endl;
return ERROR;
}
TOMfile.read((char*) TOMvolume,volumeBytes);
Я пытался затем использовать предварительно распределитель, чтобы создать вектор, который содержит эти малые c 'ed данные
std::vector<uint8_t, PreAllocator<uint8_t>> v_TOMvolume(0, PreAllocator<uint8_t>(&TOMvolume[0], volumeBytes));
v_TOMvolume.push_back(volumeBytes);
, но любая попытка прочитать размер вектора или любые данные в векторе не удалась. Данные верны в памяти, когда я просто использую отладчик для их просмотра, они просто не связываются с вектором, как мне бы хотелось.
Есть мысли? Возможно ли то, что я пытаюсь сделать?