質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2671閲覧

std::vectorを使でpush_back()するとSegmentation fault (コアダンプ)というエラーでる原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2022/05/01 02:45

編集2022/05/01 04:13

提示コードですがstd::vector<>にpush_back() すると Segmentation fault (コアダンプ)というエラーが出ますこれはなぜでしょうか?SetGridLine_X(int pos,byte b)関数でpush_backすると発生するのですが原因がかりません、また初期化しているのに要素数がおかしくなる原因もわかりません。これはなぜでしょうか?正常に実行できるときもあればSegmentation fault (コアダンプ)というエラーが出るときもありますこれはなぜでしょうか?

イメージ説明
イメージ説明

環境

OS: ubuntu
コンパイラ: g++
利用ライブラリ glm

cpp

1#include <iostream> 2#include <stdio.h> 3#include <random> 4#include <cstdarg> 5#include <sys/types.h> 6#include <glm/glm.hpp> 7 8typedef char byte; 9 10void SetArea(glm::ivec2 pos,glm::ivec2 size,byte b); 11void SetGridLine_X(int pos,byte b); 12void SetGrid(); 13int GetRandom(int start, int end); 14 15 16 17byte grid[100][100]; //グリッド 18byte b = 0x01; 19 20 21 22struct Area 23{ 24 int size; 25 glm::ivec2 start; 26 glm::ivec2 end; 27 28}; 29 30std::vector<Area> area; //エリア数 31 32 33// ##################################### 乱数 取得 ##################################### 34int GetRandom(int start, int end) 35{ 36 std::random_device rnd; // 非決定的な乱数生成器を生成 37 std::mt19937 mt(rnd()); // メルセンヌ・ツイスタの32ビット版、引数は初期シード値 38 std::uniform_int_distribution<> Rand(start, end); // [start, end] 範囲の一様乱数 39 40 return Rand(mt); 41} 42 43 44// ##################################### 一番大きいエリアを削除 ##################################### 45void DeleteArea() 46{ 47 printf("bbbbbb %d\n",area.size()); 48 49 int max = 0; 50 int i = 0; 51 Area map = Area{0,glm::ivec2(0,0),glm::ivec2(0,0)}; 52 for(std::vector<Area>::iterator itr = area.begin(); itr != area.end(); itr++) 53 { 54 printf("っっっっc: %d\n",area.size()); 55 56 if( map.size < itr->size) 57 { 58 59 map = *itr; 60 max = i; 61 printf("aaaa\n"); 62 63 //printf("size: %d\n",map.size); 64 } 65 66 i++; 67 } 68 69 if(area.size() != 0) 70 { 71 printf("eeeeeee\n"); 72 area.erase(area.begin() + max); //一番大きいエリアを削除 73 } 74 printf("cccccccc\n"); 75 76} 77 78 79 80// ##################################### 一番大きいエリアを取得 ##################################### 81Area GetArea() 82{ 83 Area map = Area{0,glm::ivec2(0,0),glm::ivec2(0,0)}; 84 for(std::vector<Area>::iterator itr = area.begin(); itr != area.end(); itr++) 85 { 86 if( map.size < itr->size) 87 { 88 map = *itr; 89 90// printf("size: %d\n",map.size); 91 } 92 } 93 94 return map; 95} 96 97// ##################################### エリアに値を設定 ##################################### 98void SetArea(glm::ivec2 pos,glm::ivec2 size,byte b) 99{ 100 for(int y = pos.y; y < pos.y + size.y; y++) 101 { 102 for(int x = pos.x; x < pos.x + size.x; x++) 103 { 104 grid[y][x] = b; 105 } 106 } 107 108 printf("ええええ\n"); 109} 110 111// ##################################### X軸でエリアを設定 ##################################### 112void SetGridLine_X(int pos,byte b) 113{ 114 Area map = GetArea(); 115 116 SetArea(map.start,glm::ivec2(pos,100),b); 117 SetArea(glm::ivec2(map.start.x + pos,0),glm::ivec2(map.end.x - map.start.x - pos,100),++b); 118 119 DeleteArea(); 120 121 if(pos > (map.end.x - map.start.x - pos)) 122 { 123 124 glm::ivec2 start; 125 start.x = map.start.x; 126 start.y = 0; 127 128 glm::ivec2 end; 129 end.x = map.start.x + pos; 130 end.y = map.end.y; 131 132 133 glm::ivec2 size = end - start; 134 int s = size.x * size.y; 135 136 printf("wwww\n"); 137 area.push_back(Area { s,start,end }); 138 139 printf("ああああ %c\n",b); 140 } 141 else 142 { 143 glm::ivec2 start; 144 start.x = map.start.x + pos; 145 start.y = 0; 146 147 glm::ivec2 end; 148 end.x = map.end.x - map.start.x - pos; 149 end.y = map.end.y; 150 151 152 glm::ivec2 size = end - start; 153 int s = size.x * size.y; 154 printf("wwww\n"); 155 156 area.push_back(Area { s,start,end }); 157 158 printf("いいいい %c\n",b); 159 160 } 161 162 163 //area.push_back(); 164 165 166 167 printf("pos: %d\n",pos); 168 printf("map.end.x - map.start.x - pos: %d\n",map.end.x - map.start.x - pos); 169 printf("map.start + pos: %d\n",map.start.x + pos); 170 171 172 173 174} 175 176 177// ##################################### グリッドを設定 ##################################### 178void SetGrid() 179{ 180 int r = GetRandom(1,99); 181 182 SetGridLine_X(r,(byte)b); 183} 184 185 186int main() 187{ 188 for(int i = 0; i < 100; i++) 189 { 190 for(int j = 0; j < 100; j++) 191 { 192 grid[i][j] = (byte)0x00; 193 } 194 } 195 196 197 area.resize(0); 198 area.push_back(Area { 100 * 100,glm::ivec2(0,0),glm::ivec2(100,100) }); 199 200 SetGrid(); 201 b++; 202 SetGrid(); 203 //SetGrid(); 204 205 206 for(int i = 0; i < 100; i++) 207 { 208 for(int j = 0; j < 100; j++) 209 { 210 switch(grid[i][j]) 211 { 212 case 0x00: 213 { 214 printf("*"); 215 } 216 break; 217 218 case 0x01: 219 { 220 printf("A"); 221 } 222 break; 223 224 case 0x02: 225 { 226 printf("B"); 227 } 228 break; 229 230 231 case 0x03: 232 { 233 printf("C"); 234 } 235 break; 236 237 238 case 0x04: 239 { 240 printf("D"); 241 } 242 break; 243 244 } 245 } 246 247 printf("\n"); 248 } 249} 250

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

std::vector<Area> area; //エリア数とグローバル変数で確保しているのが良くないのではないでしょうか?

ぐぐって見つけた
https://brain.cc.kogakuin.ac.jp/~kanamaru/lecture/MP/final/part06/node8.html
を参照下さい。

グローバル変数は参照先の「静的領域」に確保されるため,サイズが固定の時はいいのですが,可変には対応していません。push_backが呼ばれる毎におそらくstd::vector<Area> area;の後のメモリを破壊していっているのでしょう。

そこでこの場合,「ヒープ領域」に確保させるため,main関数の中で宣言する必要があるのではないでしょうか。
その後はVectorクラスのコンストラクタ等(内部でnew等を発行する)がよしなに領域を確保してくれるでしょう。

投稿2022/07/15 15:02

ujimushi_sradjp

総合スコア2091

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問