【问题标题】:C++ 3D array to 1D causes heap-buffer-overflowC ++ 3D数组到1D导致堆缓冲区溢出
【发布时间】:2017-08-20 18:12:21
【问题描述】:

我想举一个最小的例子。如果提供的代码还不够,请告诉我您还需要什么。这不是什么超级秘密;)

考虑以下两种实现:

使用 3d 数组:

.h

class Grid
{
    public:
        Grid();

        uint8_t get(int x, int y, int z);
        void set(int x, int y, int z, uint8_t value);

    private:
        uint8_t blocks[Chunk::width][Chunk::height][Chunk::depth];
};

.cpp

Grid::Grid()
{
    memset(blocks, 0, sizeof(blocks));
}

uint8_t Grid::get(int x, int y, int z)
{
    return blocks[x][y][z];
}

void Grid::set(int x, int y, int z, uint8_t value)
{
    blocks[x][y][z] = value;
}

现在是一维数组:

.h

class Grid
{
    public:
        Grid();

        uint8_t get(int x, int y, int z);
        void set(int x, int y, int z, uint8_t value);

    private:
        uint8_t blocks[Chunk::width * Chunk::height * Chunk::depth];
        int to1D(int x, int y, int z) { return x + (y * Chunk::width) + (z * Chunk::width * Chunk::height); }
};

.cpp

Grid::Grid()
{
    memset(blocks, 0, sizeof(blocks));
}

uint8_t Grid::get(int x, int y, int z)
{
    return this->blocks[x + (y * Chunk::width) + (z * Chunk::width * Chunk::height)];
}

void Grid::set(int x, int y, int z, uint8_t value)
{
    this->blocks[x + (y * Chunk::width) + (z * Chunk::width * Chunk::height)] = value;
}

现在有了 3D 版本,一切都像魅力一样,而 对于相同的整体尺寸我得到了一个

摘要:AddressSanitizer:Grid::get(int, int, int) 中的 heap-buffer-overflow src/Grid.cpp:16

我真的很想知道为什么会这样。两种实现都持有uint8_ts...我似乎看不到/掌握的 3d-array 版本中的优化是什么?

(是的,这是一个 minecrafty 体素引擎实验;))

【问题讨论】:

  • 宽度、高度和深度的值有多大?
  • 跟进@Ronin,你的代码会因为 x/y/z 的小值而崩溃吗?
  • 你从来没有说过你用什么值来调用Grid::get
  • 你的 IDE(编程环境和编译器)是什么,你遇到了什么错误?
  • 每个值都是 16。不过有很多网格

标签: c++ arrays buffer-overflow


【解决方案1】:

如果您正在为游戏构建环境,我猜您遇到了内存分配问题。假设您正在运行的游戏需要 50 MB 内存。从任何地方获取 50 MB 并不是什么大问题。但是尝试获得 50 MB 的连续内存是 waaaaaayyy 更加困难。如今,大多数操作系统都使用分页系统来跟踪已分配和未分配的内存。这里有更多信息:https://en.wikipedia.org/wiki/Paging

3D 数组基本上是一个指向指针数组的指针,每个指针都指向另一个指针数组。并且这些指针中的每一个都包含要与之交互的有限内存块。因此,在这种情况下,操作系统可以为您提供 5,000 个 50 KB 的内存块,并且指针可以将所有这些内存保存在不同的位置。

【讨论】:

  • 我不认为堆内存可以提供50MB,但为什么需要连续内存?!
  • 我刚刚扔了一个号码。但基本上他将所有信息从 3D 数组存储到 1D 数组。并且一维数组通常分配的内存量是在声明时计算的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
  • 1970-01-01
  • 2021-10-12
  • 2017-06-26
  • 1970-01-01
  • 2019-07-15
  • 2010-11-11
相关资源
最近更新 更多