#Read access violation in unordered map

19 messages · Page 1 of 1 (latest)

viscid gull
#

I have this map std::unordered_map<glm::ivec3, Chunk,IVec3Hasher> loadedChunks;
I added a hasher for ivec3:

struct IVec3Hasher
{
    std::size_t operator()(const glm::ivec3& v) const
    {
        std::hash<int> hasher;
        size_t h1 = hasher(v.x);
        size_t h2 = hasher(v.y);
        size_t h3 = hasher(v.z);
        return h1 ^ (h2 << 1) ^ (h3 << 2);
    }
};

Then it causes read access violation at loadedChunks.insert({glm::ivec3{ x,y,z }, chunk});

FastNoiseLite noise;
noise.SetNoiseType(FastNoiseLite::NoiseType_OpenSimplex2);

for (int x=0;x<terrainSize;x++)
{
    for (int z=0;z<terrainSize;z++)
    {
        for (int y = 0; y < 3; y++)
        {
            Chunk chunk{ {x,y,z},true };
            for (int bx = 0; bx < 16; bx++)
            {
                for (int by = 0; by < 16; by++)
                {
                    for (int bz = 0; bz < 16; bz++)
                    {
                        glm::ivec3 blockPosition = { x * 16,y * 16,z * 16 };
                        float noiseValue = noise.GetNoise(static_cast<float>(blockPosition.x), static_cast<float>(blockPosition.y), static_cast<float>(blockPosition.z));
                        Block block;
                        if (noiseValue < -0.5f)
                        {
                            block = Block{ terrain::soil };
                        }
                        else
                        {
                            block = Block{ terrain::stone };
                        }
                        chunk.setBlock(blockPosition.x, blockPosition.y, blockPosition.z, block);
                    }
                }
            }
            loadedChunks.insert({glm::ivec3{ x,y,z }, chunk});
        }
    }
}
summer graniteBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

wispy sand
#

how are these various tings being called

#

where/how is std::unordered_map<glm::ivec3, Chunk,IVec3Hasher> loadedChunks; created, stored and accessed

#

looking at the debugger it looks like your map is potentially uninitialized (or use-after-free)

#

e.g. you're not doing this sort of thing are you?

std::unordered_map& make_map() {
  std::unordered_map map;
  return map;// returning reference to local
}

void foo() {
  std::unordered_map& m = make_map();

  // use map here is UB and could lead to that behaviour
}
viscid gull
#

It is just a class member in the header, and the above code is in function that I call from main function

wispy sand
#

can you show me?

viscid gull
#
class Game
{
public:
    const int terrainSize{ 3 };
    const int chunkSize{ 16 };

    //
    struct Chunk
    {
        glm::ivec3 chunkPosition;
        bool loaded;
        // VkBuffer vertexBuffer;
        // VkDeviceMemory vertexMemory;
        // uint32_t vertexCount;
        std::array<Block,16*16*16> blocks;
        
        Block& getBlock(int x, int y, int z) {
            return blocks[x + 16 * (y + 16 * z)];
        }

        void setBlock(int x, int y, int z, const Block& block) {
            assert(x >= 0 && x < 16);
            assert(y >= 0 && y < 16);
            assert(z >= 0 && z < 16);
            blocks[x + 16 * (y + 16 * z)] = block;
        }

        void setBlock(int x, int y, int z, terrain type) {
            assert(x >= 0 && x < 16);
            assert(y >= 0 && y < 16);
            assert(z >= 0 && z < 16);
            blocks[x + 16 * (y + 16 * z)].type = type;
        }
    };

    std::unordered_map<glm::ivec3, Chunk,IVec3Hasher> loadedChunks={};

    void generateTerrain();
};
#
void Game::generateTerrain()
{
    FastNoiseLite noise;
    noise.SetNoiseType(FastNoiseLite::NoiseType_OpenSimplex2);

    for (int x=0;x<terrainSize;x++)
    {
        for (int z=0;z<terrainSize;z++)
        {
            for (int y = 0; y < 3; y++)
            {
                Chunk chunk{ {x,y,z},true };
                for (int bx = 0; bx < 16; bx++)
                {
                    for (int by = 0; by < 16; by++)
                    {
                        for (int bz = 0; bz < 16; bz++)
                        {
                            glm::ivec3 blockPosition = { x * 16,y * 16,z * 16 };
                            float noiseValue = noise.GetNoise(static_cast<float>(blockPosition.x), static_cast<float>(blockPosition.y), static_cast<float>(blockPosition.z));
                            Block block;
                            if (noiseValue < -0.5f)
                            {
                                block = Block{ terrain::soil };
                            }
                            else
                            {
                                block = Block{ terrain::stone };
                            }
                            chunk.setBlock(blockPosition.x, blockPosition.y, blockPosition.z, block);
                        }
                    }
                }
                loadedChunks.insert({glm::ivec3{ x,y,z }, chunk});
            }
        }
    }
}
#

And game.generateTerrain(); in the main function

wispy sand
#

its its just a byte then maybe its not too bad

#

but yeah this sort of thing should work

#

have you heard of address sanitizer?

summer graniteBOT
#
Address Sanitizer

Memory errors are common in C and C++ and can be hard to debug because they often manifest far from their source.

Address sanitizer is a runtime tool that identifies memory errors at their source and makes debugging much simpler. This is an essential tool for C and C++ software development.

Address sanitizer is available for gcc/clang on linux and msvc on windows. To use it, simply pass the flag -fsanitize=address to the compiler.

For a detailed walkthrough, see tccpp Address Sanitizer

wispy sand
#

try using this and see what it comes up with

viscid gull
#

ok, I haven't heard about them

wispy sand
#

its very simple, you pass the flag and it hopefully find the memory errors by adding extra checks into the code