简体   繁体   中英

C++ 3D array to 1D causes heap-buffer-overflow

I want to give a minimal example. If the code provided is not enough, please tell me what else you need. It's nothing super secret ;)

Consider the following two implementations:

Using 3d array:

.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;
}

Now a 1D array:

.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;
}

Now with the 3D version everything works like a charm, while for the same overall size I get a

SUMMARY: AddressSanitizer: heap-buffer-overflow src/Grid.cpp:16 in Grid::get(int, int, int)

And I really wonder why that is. Both implementations hold uint8_t s... What is the optimization going on in the 3d-array version I cannot seem to see/grasp?

(Yes, this is a minecrafty voxel engine experiment ;))

If you're building an environment for a game, my guess is you're having memory allocation issues. Lets say that you need 50 MB of memory for the game you're running. Getting that 50 MB from anywhere isn't a big deal. But trying to get 50 MB of continuous memory is waaaaaayyy more difficult. Most OS's these days use a paging system to keep track of allocated and unallocated memory. Here's more info: https://en.wikipedia.org/wiki/Paging

A 3D array is basically a pointer to a array of pointers, of each of these pointers point to another array of pointers. And each of those pointers contains a finite chunk of memory to interact with. So in this case the OS can give you 5,000 50 KB chunks of memory and the pointers can keep all of this memory in different places.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM