88597


提示コードですが`SetGridLine_X(int pos,byte
b)`関数部で以下の提示画像のエラーが発生します。これはなぜでしょうか？`area`変数を初期化しているのにもかからず要素数がおかしくなります。また`push_back`しているところで`Segmentation
fault (コアダンプ)`というエラーも出ます。何回かに一回発生します。これは何が原因なのでしょうか？

##### 試したこと

printf()で色々変数の中身を確認しました。

##### 環境

コンパイラ g++  
OS ubuntu

※ コードはダンジョンゲームのマップ生成アルゴリズムの縦分割するコードです。  
参考サイト： https://kt2525family.com/rogue-development-5/

[![画像の説明をここに入力](https://i.stack.imgur.com/bu9pU.png)](https://i.stack.imgur.com/bu9pU.png)  
[![画像の説明をここに入力](https://i.stack.imgur.com/1c6Lc.png)](https://i.stack.imgur.com/1c6Lc.png)

[code]

    #include <iostream>
    #include <stdio.h>
    #include <random>
    #include <cstdarg>
    #include <sys/types.h>
    #include <glm/glm.hpp>
    
    typedef char byte;
    
    void SetArea(glm::ivec2 pos,glm::ivec2 size,byte b);
    void SetGridLine_X(int pos,byte b);
    void SetGrid();
    int GetRandom(int start, int end);
    
    
    
    byte grid[100][100];    //グリッド
    byte b = 0x01;
    
    
    
    struct Area
    {
        int size;
        glm::ivec2 start;
        glm::ivec2 end;
    
    };
    
    std::vector<Area> area; //エリア数
    
    
    // ##################################### 乱数　取得 ##################################### 
    int GetRandom(int start, int end)
    {
        std::random_device rnd;                             // 非決定的な乱数生成器を生成
        std::mt19937 mt(rnd());                             //  メルセンヌ・ツイスタの32ビット版、引数は初期シード値
        std::uniform_int_distribution<> Rand(start, end);   // [start, end] 範囲の一様乱数 
    
        return Rand(mt);
    }
    
    
    // ##################################### 一番大きいエリアを削除 ##################################### 
    void DeleteArea()
    {
        printf("bbbbbb %d\n",area.size());
    
        int max = 0;
        int i = 0;
        Area map = Area{0,glm::ivec2(0,0),glm::ivec2(0,0)};
        for(std::vector<Area>::iterator itr = area.begin(); itr != area.end(); itr++)
        {
        printf("っっっっｃ: %d\n",area.size());
    
            if( map.size < itr->size)
            {
    
                map = *itr;
                max = i;
        printf("aaaa\n");
    
                //printf("size: %d\n",map.size);
            }     
    
            i++;   
        }
    
        if(area.size() != 0)
        {
            printf("eeeeeee\n");
            area.erase(area.begin() + max); //一番大きいエリアを削除
        }
        printf("cccccccc\n");
    
    }
    
    
    
    // ##################################### 一番大きいエリアを取得 ##################################### 
    Area GetArea()
    {
        Area map = Area{0,glm::ivec2(0,0),glm::ivec2(0,0)};
        for(std::vector<Area>::iterator itr = area.begin(); itr != area.end(); itr++)
        {
            if( map.size < itr->size)
            {
                map = *itr;
    
    //            printf("size: %d\n",map.size);
            }        
        }
    
        return map;
    }
    
    // ##################################### エリアに値を設定 ##################################### 
    void SetArea(glm::ivec2 pos,glm::ivec2 size,byte b)
    {
        for(int y = pos.y; y < pos.y + size.y; y++)
        {
            for(int x = pos.x; x < pos.x + size.x; x++)
            {
                grid[y][x] = b;
            }
        }
    
        printf("ええええ\n");
    }
    
    // ##################################### X軸でエリアを設定 ##################################### 
    void SetGridLine_X(int pos,byte b)
    {
        Area map = GetArea();
    
        SetArea(map.start,glm::ivec2(pos,100),b);
        SetArea(glm::ivec2(map.start.x + pos,0),glm::ivec2(map.end.x - map.start.x - pos,100),++b);
    
        DeleteArea();
    
        if(pos > (map.end.x - map.start.x - pos))
        {
    
            glm::ivec2 start;
            start.x = map.start.x;
            start.y = 0;
    
            glm::ivec2 end;
            end.x = map.start.x + pos;
            end.y = map.end.y;
    
    
            glm::ivec2 size = end - start;
            int s = size.x * size.y;
    
            printf("wwww\n");        
            area.push_back(Area { s,start,end });
    
            printf("ああああ　%c\n",b);
        }
        else
        {
            glm::ivec2 start;
            start.x = map.start.x + pos;
            start.y = 0;
    
            glm::ivec2 end;
            end.x = map.end.x - map.start.x - pos;
            end.y = map.end.y;
    
    
            glm::ivec2 size = end - start;
            int s = size.x * size.y;
            printf("wwww\n");        
    
            area.push_back(Area { s,start,end });
    
            printf("いいいい　%c\n",b);
    
        }
    
    
        //area.push_back();
    
    
    
        printf("pos: %d\n",pos);
        printf("map.end.x - map.start.x - pos: %d\n",map.end.x - map.start.x - pos);
        printf("map.start + pos: %d\n",map.start.x + pos);
    
    
    
    
    }
    
    
    // ##################################### グリッドを設定 ##################################### 
    void SetGrid()
    {
        int r = GetRandom(1,99);
    
        SetGridLine_X(r,(byte)b);    
    }
    
    
    int main()
    {
        for(int i = 0; i < 100; i++)
        {
            for(int j = 0; j < 100; j++)
            {
                grid[i][j] = (byte)0x00;
            }    
        }   
    
        
        area.resize(0);
        area.push_back(Area { 100 * 100,glm::ivec2(0,0),glm::ivec2(100,100) });
    
        SetGrid();
        b++;
        SetGrid(); 
        //SetGrid();
    
    
        for(int i = 0; i < 100; i++)
        {
            for(int j = 0; j < 100; j++)
            {
                switch(grid[i][j])
                {
                    case 0x00:
                    {
                        printf("*");
                    }
                    break;
    
                    case 0x01:
                    {
                        printf("A");
                    }
                    break;
    
                    case 0x02:
                    {
                        printf("B");
                    }
                    break;
                    
    
                    case 0x03:
                    {
                        printf("C");
                    }
                    break;
                    
    
                    case 0x04:
                    {
                        printf("D");
                    }
                    break;
                    
                }
            }   
    
            printf("\n"); 
        }   
    }
    
    
[/code]


CC BY-SA 4.0
2022-05-01T04:19:52.877
88596
2022-05-03T23:46:38.880
2022-05-03T23:46:38.880
4236
question
c++
std::vector<> push_back() 関数でSegmentation fault (コアダンプ)というエラーでる原因が知りたい。


>
[code]

>     byte grid[100][100];    //グリッド
>     byte b = 0x01;
>  
>     struct Area
>     {
>         int size;
>         glm::ivec2 start;
>         glm::ivec2 end;
>     };
>  
>     std::vector<Area> area; //エリア数
>  
[/code]

とのことですので、`grid`が本来の範囲を超えてアクセスを行っており、それによって`area`が破壊されている可能性が考えられます。  
`grid`にアクセスする際に範囲を超えていないか確認することをお勧めします。例えば、

>
[code]

>     void SetArea(glm::ivec2 pos,glm::ivec2 size,byte b)
>     {
>         for(int y = pos.y; y < pos.y + size.y; y++)
>         {
>             for(int x = pos.x; x < pos.x + size.x; x++)
>             {
>                 grid[y][x] = b;
>  
[/code]

で`x`や`y`が100を超えているかもしれません。つまり、`pos.x + size.x`や`pos.y +
size.y`が100を超えているかもしれません。


CC BY-SA 4.0
2022-05-01T04:45:22.903
88597
2022-05-01T04:45:22.903
4236
88596
answer