gpt4 book ai didi

c++ - 制作一个指向已分配内存的 C++ vector

转载 作者:行者123 更新时间:2023-12-01 14:48:29 24 4
gpt4 key购买 nike

我正在使用一些旧代码,这些代码分配了一块 RAM,然后将一个二进制文件加载到其中。二进制文件是一系列 8 位灰度图像平面,X 乘 Y 大小,Z 平面深。这些文件通常在 500 兆字节到 10 吉字节之间。

现有代码使用复杂的指针排列来访问 XY、XZ 或 YZ 平面中的各个平面。

我想做的是用单个 vector vector 替换指针,其中每个子 vector 是数据中的一个 XY 平面。这样做的目的是获得一些安全性并检查您获得的 vector 而不是原始指针访问。

基于上一个问题( Is it possible to initialize std::vector over already allocated memory? ),我有以下代码

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

然后我尝试使用预分配器来创建一个保存这个 malloc 数据的 vector
std::vector<uint8_t, PreAllocator<uint8_t>> v_TOMvolume(0, PreAllocator<uint8_t>(&TOMvolume[0], volumeBytes));
v_TOMvolume.push_back(volumeBytes);

但是任何读取 vector 大小或 vector 中任何数据的尝试都失败了。当我只使用调试器查看数据时,数据在内存中是正确的,只是没有与 vector 相关联,正如我所希望的那样。

有什么想法吗?我正在尝试做的可能吗?

最佳答案

不可能在保留内存的先前内容的同时为 vector 分配内存。

一种工作方法:

  • 根本不要使用 malloc。
  • 使用默认分配器创建一个具有必要大小的 vector 。
  • 将二进制文件直接加载到 vector 中。


  • 在假设的情况下,您无法触摸分配部分,因为它位于库深处的某个地方:只是不要使用 vector 。您已经有一个动态数组。基于迭代器的算法与指针一起工作得很好。对于基于范围的算法,你需要类似 std::span 的东西(C++20) 或类似的。

    但是使用 vector 进行分配会更安全,因此更好。

    如果您的文件最大为 10 GB,那么我建议您尝试使用内存映射该文件。映射内存也不能用作 vector 的存储,所以应该采取不使用 vector 的方法。不幸的是,内存映射文件没有标准的方法。

    关于c++ - 制作一个指向已分配内存的 C++ vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60729075/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com