【问题标题】:Random access to array of raw buffers of different sizes?随机访问不同大小的原始缓冲区数组?
【发布时间】:2019-03-21 16:43:37
【问题描述】:

我有一个数组数组:struct chunk { char * data; size_t size; }; chunk * chunks;。每个块中的数据大小是动态的,并且在块之间有所不同。使用嵌套的 for 循环可以轻松地线性访问数据:

for (chunk * chunk_it = chunks; chunk_it != chunks + count; ++chunk_it) {
    for (char * it = chunk_it->data; it != chunk_it->data + chunk_it->size; ++it) {
        /* use it here */
    }
}

我想把它变成对chunks->data 的随机访问,使用operator[] 作为接口,跨越多个块

它的工作原理是线性搜索正确的块,然后只计算我想要的数据的偏移量。

template <class T>
void random_access(int n) {
    chunk * c;
    for (int i = 0; i < count; ++i) {
        c = chunks + i;
        size_t size = c->size;
        if (n - size < 0) {
            n -= size; // mutate n to fit into current chunk
        } else {
            break; // found
        }
    }

    T * data = reinterpret_cast<T *>(c->data + n);

    // use data here
}

有没有更有效的方法来做到这一点?每次我需要大块中的 T 时,这样做会很疯狂。我计划线性迭代所有块数据,但我想在函数之外使用数据,因此需要在内部循环中返回它(因此我想把它翻过来)。我也想过在内部循环中使用函数指针,但不是像 chunk_iterator[n] 这样更好。

【问题讨论】:

  • C++ 数组 应该是 std::arraystd::vector... 你没有在这里使用 C...
  • 有什么具体原因不能使用std::vector&lt;std::string&gt; chunks
  • 每当你调用random_access()时,很容易说“无法解析标识符c”...变量chunk * c是在循环内部,这将如何编译!
  • 您可以将所有块组成一个连续块,并将指向各个块的指针存储在 chunks 数组中。
  • 使用树? (你可以使用 std::set::lower_bound 来避免实现你自己的)

标签: c++ arrays iterator random-access


【解决方案1】:

我了解您的数据结构更复杂,但您不能这样做吗?

我构建了一个连续的chunk data块,并在chunks array中记录了每一个的positionsize /em>:

class chunk_manager
{
    struct chunk
    {
        std::size_t position;
        std::size_t size;

        chunk(std::size_t position, std::size_t size)
        : position(position), size(size) {}
    };

public:

    void add_chunk(std::string const& chunk)
    {
        m_chunks.emplace_back(m_data.size(), chunk.size());
        m_data.append(chunk);
    }

    char* random_access(std::size_t n) { return &m_data[n]; }

    std::size_t size_in_bytes() const { return m_data.size(); }

private:
    std::vector<chunk> m_chunks;
    std::string m_data;
};

int main()
{
    chunk_manager cm;

    cm.add_chunk("abc");
    cm.add_chunk("def");
    cm.add_chunk("ghi");

    for(auto n = 0ULL; n < cm.size_in_bytes(); ++n)
        std::cout << cm.random_access(n) << '\n';
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    相关资源
    最近更新 更多