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

A very big array ( continuous chunk of memory)

本文关键字:数组 连续 内存 非常 一个      更新时间:2023-10-16

我正在学习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元素,所以我们需要一个非常长的连续内存块。但是要获得这么大的内存块是不可能的(可能吗?)

请解释一下。

不要一次将所有的map放入内存。无论如何,玩家都不可能看到所有内容。相反,我们应该只设置玩家所在的贴图,并在玩家周围的各个方向添加一定数量的贴图。

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

根据MSDN:

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

所以大数组的分配没有问题,但是仍然有机会进入内存碎片