一个非常大的数组(连续的内存块)

时间:2015-08-20 09:23:36

标签: c++ cocos2d-x

我正在学习Cocos2dx,而且我正在使用平铺地图。 所以,让我们考虑以下代码:

 auto map = TMXTiledMap::create("map.tmx");
 auto layer = map->getLayer("Tile Layer 1");   
 auto gid = layer->tileGIDAt(Point(X, Y));

最后一行对我很重要。我很困惑,因为我看到了tileGIDAt(Point)的实现:

uint32_t TMXLayer::getTileGIDAt(const Vec2& pos, TMXTileFlags* flags/* = nullptr*/)
{
    CCASSERT(pos.x < _layerSize.width && pos.y < _layerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
    CCASSERT(_tiles && _atlasIndexArray, "TMXLayer: the tiles map has been released");

    ssize_t idx = static_cast<int>((pos.x + pos.y * _layerSize.width));
    // Bits on the far end of the 32-bit global tile ID are used for tile flags
    uint32_t tile = _tiles[idx];

    // issue1264, flipped tiles can be changed dynamically
    if (flags) 
    {
        *flags = (TMXTileFlags)(tile & kTMXFlipedAll);
    }

    return (tile & kTMXFlippedMask);
}

所以,我很困惑,因为地图似乎在内存中表示为数组。

为什么可能?这对我很重要,因为你知道平铺地图可能非常大。关于大小的地图是什么:1000000个瓷砖x 1000000个瓷砖。结果我们应该采用1000000 ^ 2个Tile元素,因此我们需要一个非常长的连续内存块。但是不可能获得如此大的内存(是否可能?)。

请解释一下。

2 个答案:

答案 0 :(得分:2)

不要一次将所有地图放入内存。无论如何,玩家几乎无法看到所有这些。相反,只有玩家所在的牌,以及玩家周围所有方向的一定数量的牌。

然后,当玩家移动时,从您在磁盘上的任何地图加载新的磁贴信息,或者如果您执行程序磁贴,则生成,将内存中的磁贴替换为您加载/生成的新磁贴。

答案 1 :(得分:1)

根据MSDN:

  

进程的虚拟地址空间是它可以使用的一组虚拟内存地址。每个进程的地址空间都是私有的,除非共享,否则其他进程无法访问。   虚拟地址不代表对象在内存中的实际物理位置;相反,系统为每个进程维护一个页表,这是一个内部数据结构,用于将虚拟地址转换为相应的物理地址。每次线程引用地址时,系统都会将虚拟地址转换为物理地址。

所以分配大型数组没有问题,但仍有机会进入hip memory fragmentation