Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否可以使多索引容器使用连续内存?_C++_Memory_Boost Multi Index - Fatal编程技术网

C++ 是否可以使多索引容器使用连续内存?

C++ 是否可以使多索引容器使用连续内存?,c++,memory,boost-multi-index,C++,Memory,Boost Multi Index,这里我有一个简单的multi_索引容器,我想知道是否有办法强制multi_索引在内存中连续分配元素。我认为如果主索引是随机访问,这是可能的 然而,这个简单的示例显示,这些元素在内存中意外地不连续是否存在可能导致连续内存的组合boost::multi_index::index_by #include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #includ

这里我有一个简单的multi_索引容器,我想知道是否有办法强制multi_索引在内存中连续分配元素。我认为如果主索引是
随机访问
,这是可能的

然而,这个简单的示例显示,这些元素在内存中意外地不连续是否存在可能导致连续内存的组合
boost::multi_index::index_by

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>

int main(){
    typedef boost::multi_index_container<
        double,  // simply store doubles
        boost::multi_index::indexed_by<
            boost::multi_index::random_access<>
        >
    > random_access_container;

    random_access_container v; // fill container
    v.reserve(10); // also tried this
    v.push_back(1.);
    v.push_back(2.);
    v.push_back(3.);

    assert( v[0] == 1. ); // ok
    assert( *(&v[0] + 1) == v[1] ); // this fails, memory is not contiguous
}
#包括
#包括
#包括
#包括
#包括
int main(){
typedef boost::多索引容器<
double,//只存储double
boost::多索引::按索引索引<
boost::多索引::随机访问
>
>随机存取容器;
随机访问容器v;//填充容器
v、 保留(10);//也尝试过这个
v、 向后推(1);
v、 向后推(2);
v、 向后推(3);
断言(v[0]==1.);//确定
assert(*(&v[0]+1)==v[1]);//此操作失败,内存不连续
}
注1:我希望这样做是为了兼容性(这样我可以利用
multi_index
容器--与其他访问选项--),但也可以使用直接内存访问(就像
std::vector
一样)

注2:我刚从文档中找到这句话,所以看起来很难

除非另有说明或相应接口不存在, 随机访问索引验证的容器要求与 std::vector加上std::列表特定列表的要求 [list.ops]上的操作。与 关于std::vector,如下所示:

  • 随机访问索引不提供内存连续性,因此没有数据成员函数


  • 不,你没有记忆连续性。随机访问索引的布局类似于:

    如果将元素(例如
    T
    )存储在
    std::vector
    中,然后使用
    std::ref
    s的
    multi_index_容器
    ,则可以获得连续内存的近似值。当然,这会使对象生命周期管理复杂化

    编辑:设计原理

    内存连续性难以/难以包含在库设计中的原因有很多:

    • 迭代器稳定性由所有索引提供,而不仅仅是随机访问索引。如果元素连续存储在内存块中,就不可能保持这种状态(具有合理的性能)
    • 假设我们设法获得了一个随机访问索引,该索引导致了关于元素存储的内存连续性。如果我们有两个随机访问索引,会发生什么?似乎容器的第一个索引应该有一个特殊的地位,它决定了整个容器的布局,以使容器能够容纳水
    • 非随机访问索引根据需要基于节点。这意味着每个值都存储在一个更大的结构中,并有空间容纳额外的信息(rb树指针等)。如果元素是连续存储的,那么a)将是连续存储的节点,而不是值本身,这看起来非常无用(想想
      data()
      将返回什么),或者b)必须将节点与值分离,这样,我们就不用在节点中嵌入值,而是让节点具有指向连续存储值的指针,这是一种空间浪费,看起来不像是合理的默认决策

    这是因为(迭代器)稳定性是设计中的优先事项吗?原则上,reserve函数可以实现这一点,但我想它会使实现变得非常复杂,不是吗?我已经在我的回答中添加了一些注释,希望能解决您的问题。好的,我明白您的意思了。如果您想要节点连续性(与值连续性相反),可能可以求助于某个池分配器。请注意,随机访问索引的
    reserve
    与此无关,因为它仅适用于索引的内部指针数组(参见图)。最后,我看不出什么节点连续性是有用的(特别是因为作为用户,您不知道节点类型)。@alfC我担心:
    reserve
    只影响索引指针数组(我的响应中显示的图中的上向量),没有实际的节点是真正预先分配的。@alfC在一天结束时,
    multi\u index\u contaner
    是一个基于节点的容器,在这方面的行为非常类似于,比如说,
    std::set
    ,它也没有
    保留。您可能希望使用基于池的分配器来查看这是否提高了效率和/或缓存位置。