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

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

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

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

Q&A

解決済

3回答

7026閲覧

c++の学校の課題でfree();:invalid size Aborted(core dumped)の原因がわかりません。

akaikesan

総合スコア23

C++

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

0グッド

0クリップ

投稿2019/05/11 22:06

前提・実現したいこと

学校の課題の
エラーの原因を知りたい、エラーを解決したい

発生している問題・エラーメッセージ

free(): invalid size Aborted (core dumped)

該当のソースコード

C++

1#include <curses.h> 2#include <stdlib.h> 3 4//ぷよの色を表すの列挙型 5//NONEが無し,RED,BLUE,..が色を表す 6enum puyocolor { NONE, RED, BLUE, GREEN, YELLOW }; 7 8 9//メモリ開放 10class PuyoArray{ 11private: 12 //盤面状態 13 puyocolor *data; 14 //盤面の行数,列数 15 unsigned int data_line; 16 unsigned int data_column; 17 18 19 void Release() 20 { 21 if (data == NULL) { 22 return; 23 } 24 delete[] data; 25 data = NULL; 26 } 27 28 29public: 30 PuyoArray(){ 31 //盤面状態 32 puyocolor *data = NULL; 33 //盤面の行数,列数 34 unsigned int data_line = 0; 35 unsigned int data_column = 0; 36 37 38 } 39 ~PuyoArray(){ 40 Release(); 41 } 42 43 void ChangeSize(unsigned int line, unsigned int column) 44 { 45 Release(); 46 47 //新しいサイズでメモリ確保 48 data = new puyocolor[line*column]; 49 50 data_line = line; 51 data_column = column; 52 } 53 54 //盤面の行数を返す 55 unsigned int GetLine() 56 { 57 return data_line; 58 } 59 60 //盤面の列数を返す 61 unsigned int GetColumn() 62 { 63 return data_column; 64 } 65 66 //盤面の指定された位置の値を返す 67 puyocolor GetValue(unsigned int y, unsigned int x) 68 { 69 if (y >= GetLine() || x >= GetColumn()) 70 { 71 //引数の値が正しくない 72 return NONE; 73 } 74 75 return data[y*GetColumn() + x]; 76 } 77 78 //盤面の指定された位置に値を書き込む 79 void SetValue(unsigned int y, unsigned int x, puyocolor value) 80 { 81 if (y >= GetLine() || x >= GetColumn()) 82 { 83 //引数の値が正しくない 84 return; 85 } 86 87 data[y*GetColumn() + x] = value; 88 } 89 90}; 91 92 93 94//盤面サイズ変更 95class PuyoControl{ 96public: 97//盤面に新しいぷよ生成 98 void GeneratePuyo(PuyoArray &puyo) 99 { 100 init_pair(0, COLOR_WHITE, COLOR_BLACK); 101 init_pair(1, COLOR_BLUE, COLOR_BLACK); 102 init_pair(2, COLOR_GREEN, COLOR_BLACK); 103 init_pair(3, COLOR_YELLOW, COLOR_BLACK); 104 init_pair(4, COLOR_RED, COLOR_BLACK); 105 106 107 108 puyo.SetValue(0, 5, static_cast<puyocolor>(rand() % 4 + 1)); 109 110 puyo.SetValue(0, 6, static_cast<puyocolor>(rand() % 4 + 1)); 111 } 112 113 //ぷよの着地判定.着地判定があるとtrueを返す 114 bool LandingPuyo(PuyoArray &puyo) 115 { 116 bool landed = false; 117 118 for (int y = 0; y < puyo.GetLine(); y++) 119 { 120 for (int x = 0; x < puyo.GetColumn(); x++) 121 { 122 if (puyo.GetValue(y, x) != NONE && y == puyo.GetLine() - 1) 123 { 124 landed = true; 125 126 //着地判定されたぷよを消す.本処理は必要に応じて変更する. 127 puyo.SetValue(y, x, NONE); 128 } 129 } 130 } 131 132 return landed; 133 } 134 135 //左移動 136 void MoveLeft(PuyoArray &puyo) 137 { 138 //一時的格納場所メモリ確保 139 puyocolor *puyo_temp = new puyocolor[puyo.GetLine()*puyo.GetColumn()]; 140 141 for (int i = 0; i < puyo.GetLine()*puyo.GetColumn(); i++) 142 { 143 puyo_temp[i] = NONE; 144 } 145 146 //1つ左の位置にpuyoactiveからpuyo_tempへとコピー 147 for (int y = 0; y < puyo.GetLine(); y++) 148 { 149 for (int x = 0; x < puyo.GetColumn(); x++) 150 { 151 if (puyo.GetValue(y, x) == NONE) { 152 continue; 153 } 154 155 if (0 < x && puyo.GetValue(y, x - 1) == NONE) 156 { 157 puyo_temp[y*puyo.GetColumn() + (x - 1)] = puyo.GetValue(y, x); 158 //コピー後に元位置のpuyoactiveのデータは消す 159 puyo.SetValue(y, x, NONE); 160 } 161 else 162 { 163 puyo_temp[y*puyo.GetColumn() + x] = puyo.GetValue(y, x); 164 } 165 } 166 } 167 168 //puyo_tempからpuyoactiveへコピー 169 for (int y = 0; y < puyo.GetLine(); y++) 170 { 171 for (int x = 0; x < puyo.GetColumn(); x++) 172 { 173 puyo.SetValue(y, x, puyo_temp[y*puyo.GetColumn() + x]); 174 } 175 } 176 177 //一時的格納場所メモリ解放 178 delete[] puyo_temp; 179 } 180 181 //右移動 182 void MoveRight(PuyoArray &puyo) 183 { 184 //一時的格納場所メモリ確保 185 puyocolor *puyo_temp = new puyocolor[puyo.GetLine()*puyo.GetColumn()]; 186 187 for (int i = 0; i < puyo.GetLine()*puyo.GetColumn(); i++) 188 { 189 puyo_temp[i] = NONE; 190 } 191 192 //1つ右の位置にpuyoactiveからpuyo_tempへとコピー 193 for (int y = 0; y < puyo.GetLine(); y++) 194 { 195 for (int x = puyo.GetColumn() - 1; x >= 0; x--) 196 { 197 if (puyo.GetValue(y, x) == NONE) { 198 continue; 199 } 200 201 if (x < puyo.GetColumn() - 1 && puyo.GetValue(y, x + 1) == NONE) 202 { 203 puyo_temp[y*puyo.GetColumn() + (x + 1)] = puyo.GetValue(y, x); 204 //コピー後に元位置のpuyoactiveのデータは消す 205 puyo.SetValue(y, x, NONE); 206 } 207 else 208 { 209 puyo_temp[y*puyo.GetColumn() + x] = puyo.GetValue(y, x); 210 } 211 } 212 } 213 214 //puyo_tempからpuyoactiveへコピー 215 for (int y = 0; y <puyo.GetLine(); y++) 216 { 217 for (int x = 0; x <puyo.GetColumn(); x++) 218 { 219 puyo.SetValue(y, x, puyo_temp[y*puyo.GetColumn() + x]); 220 } 221 } 222 223 //一時的格納場所メモリ解放 224 delete[] puyo_temp; 225 } 226 227 //下移動 228 void MoveDown(PuyoArray &puyo) 229 { 230 //一時的格納場所メモリ確保 231 puyocolor *puyo_temp = new puyocolor[puyo.GetLine()*puyo.GetColumn()]; 232 233 for (int i = 0; i < puyo.GetLine()*puyo.GetColumn(); i++) 234 { 235 puyo_temp[i] = NONE; 236 } 237 238 //1つ下の位置にpuyoactiveからpuyo_tempへとコピー 239 for (int y = puyo.GetLine() - 1; y >= 0; y--) 240 { 241 for (int x = 0; x < puyo.GetColumn(); x++) 242 { 243 if (puyo.GetValue(y, x) == NONE) { 244 continue; 245 } 246 247 if (y < puyo.GetLine() - 1 && puyo.GetValue(y + 1, x) == NONE) 248 { 249 puyo_temp[(y + 1)*puyo.GetColumn() + x] = puyo.GetValue(y, x); 250 //コピー後に元位置のpuyoactiveのデータは消す 251 puyo.SetValue(y, x, NONE); 252 } 253 else 254 { 255 puyo_temp[y*puyo.GetColumn() + x] = puyo.GetValue(y, x); 256 } 257 } 258 } 259 260 //puyo_tempからpuyoactiveへコピー 261 for (int y = 0; y < puyo.GetLine(); y++) 262 { 263 for (int x = 0; x < puyo.GetColumn(); x++) 264 { 265 puyo.SetValue(y, x, puyo_temp[y*puyo.GetColumn() + x]); 266 } 267 } 268 269 //一時的格納場所メモリ解放 270 delete[] puyo_temp; 271 } 272 273 274 //表示 275}; 276void Display(PuyoArray &puyo) 277{ 278 //落下中ぷよ表示 279 for (int y = 0; y < puyo.GetLine(); y++) 280 { 281 for (int x = 0; x < puyo.GetColumn(); x++) 282 { 283 switch (puyo.GetValue(y, x)) 284 { 285 case NONE: 286 attrset(COLOR_PAIR(0)); 287 mvaddch(y, x, '.'); 288 break; 289 case RED: 290 attrset(COLOR_PAIR(4)); 291 mvaddch(y, x, 'R'); 292 break; 293 case BLUE: 294 attrset(COLOR_PAIR(1)); 295 mvaddch(y, x, 'B'); 296 break; 297 case GREEN: 298 attrset(COLOR_PAIR(2)); 299 mvaddch(y, x, 'G'); 300 break; 301 case YELLOW: 302 attrset(COLOR_PAIR(3)); 303 mvaddch(y, x, 'Y'); 304 break; 305 default: 306 mvaddch(y, x, '?'); 307 break; 308 } 309 310 } 311 } 312 313 314 //情報表示 315 int count = 0; 316 for (int y = 0; y < puyo.GetLine(); y++) 317 { 318 for (int x = 0; x < puyo.GetColumn(); x++) 319 { 320 if (puyo.GetValue(y, x) != NONE) 321 { 322 count++; 323 } 324 } 325 } 326 327 char msg[256]; 328 sprintf(msg, "Field: %d x %d, Puyo number: %03d", puyo.GetLine(), puyo.GetColumn(), count); 329 mvaddstr(2, COLS - 35, msg); 330 331 refresh(); 332} 333 334//ここから実行される 335int main(int argc, char **argv){ 336 PuyoArray puyo; 337 PuyoControl ctrl; 338 //画面の初期化 339 initscr(); 340 //カラー属性を扱うための初期化 341 start_color(); 342 343 //キーを押しても画面に表示しない 344 noecho(); 345 //キー入力を即座に受け付ける 346 cbreak(); 347 348 curs_set(0); 349 //キー入力受付方法指定 350 keypad(stdscr, TRUE); 351 352 //キー入力非ブロッキングモード 353 timeout(0); 354 355 356 //初期化処理 357 puyo.ChangeSize(LINES/2, COLS/2); //フィールドは画面サイズの縦横1/2にする 358 ctrl.GeneratePuyo(puyo); //最初のぷよ生成 359 360 int delay = 0; 361 int waitCount = 20000; 362 363 int puyostate = 0; 364 365 366 //メイン処理ループ 367 while (1) 368 { 369 //キー入力受付 370 int ch; 371 ch = getch(); 372 373 //Qの入力で終了 374 if (ch == 'Q') 375 { 376 break; 377 } 378 379 //入力キーごとの処理 380 switch (ch) 381 { 382 case KEY_LEFT: 383 ctrl.MoveLeft(puyo); 384 break; 385 case KEY_RIGHT: 386 ctrl.MoveRight(puyo); 387 break; 388 case 'z': 389 //ぷよ回転処理 390 break; 391 default: 392 break; 393 } 394 395 396 //処理速度調整のためのif文 397 if (delay%waitCount == 0){ 398 //ぷよ下に移動 399 ctrl.MoveDown(puyo); 400 401 //ぷよ着地判定 402 if (ctrl.LandingPuyo(puyo)) 403 { 404 //着地していたら新しいぷよ生成 405 ctrl.GeneratePuyo(puyo); 406 } 407 } 408 delay++; 409 410 //表示 411 Display(puyo); 412 } 413 414 415 //画面をリセット 416 endwin(); 417 418 return 0; 419} 420 421

補足情報(FW/ツールのバージョンなど)

どこがおかしいのか全く検討がつきません。どうか助けてください

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

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

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

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

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

guest

回答3

0

ベストアンサー

public:
PuyoArray(){
//盤面状態
puyocolor *data = NULL;
//盤面の行数,列数
unsigned int data_line = 0;
unsigned int data_column = 0;
}

コンストラクタ内でメンバ変数の初期化ではなくローカル変数を定義しています。

投稿2019/05/11 23:47

asm

総合スコア15147

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

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

akaikesan

2019/05/12 04:38

puyocolor *data; //盤面の行数,列数 unsigned int data_line; unsigned int data_column; public: PuyoArray() { data = NULL; //盤面の行数,列数 data_line = 0; data_column = 0; } このようにしたらうまく行きました。 コンストラクタ内ではローカル変数は定義できないという解釈でよろしいのでしょうか?
asm

2019/05/12 04:56

ローカル変数へ代入したところで、同名のメンバ変数へは代入できないということです。 メンバ変数と同名のローカル変数を宣言した事で、メンバ変数が隠れてしまうのです。
akaikesan

2019/05/12 05:01

理解できたと思います。 ありがとうございました。
guest

0

PuyoArray を new して delete するだけのコードを書いて動かしてみてください。
おそらく同じエラーが出ます。
Release() では delete[] 後に data に NULL を代入していますから(蛇足ですが data == NULL の検査は不要です)、それ以外に data に NULL でもなく new したものでもないデータが入るケースがあるはずです。

ところで、課題はこのプログラムを書いて出すことですか? 単にこのプログラムのデバッグ(プログラムは与えられたもの)ですか? 後者だとヒントを出しすぎたかもしれません。

投稿2019/05/11 23:03

編集2019/05/11 23:30
cugel

総合スコア220

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

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

akaikesan

2019/05/12 05:01

やってみました。 考える機会を下さり感謝します。
guest

0

Release(部分だと思うけど)デバッグしたら?

投稿2019/05/11 22:46

cateye

総合スコア6851

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

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

akaikesan

2019/05/12 04:23

やってみたらReleaseで止まりました お答えありがとうございます
cateye

2019/05/12 09:18

スマホで回答したんで言葉足らずだった^^; 通常メモリ解放でエラーになるのは、開放時のアドレスが違っている&アドレスがNULLではない場合です。 なので、そのへんを手掛かりにブレークを貼って開放するアドレスを確認すればたいてい解決します。 ・・・間違っていたら、それが何処で設定された値なのかを確認しましょうd^^
akaikesan

2019/05/12 11:07

参考にします ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問