前提・実現したいこと
誰か分かる方、助けてください...!
レポートで、C言語のSDLライブラリを用いた以下のプログラムを書いています。
・ウィンドウに,円と四角を描画する
・マウス(カーソル)の現在座標をウィンドウ上に表示する(stringColor関数,sprintf関数を使う)
・円をマウスでドラッグアンドドロップできる
・円を四角の中にドロップすると,“GoodJob!”という文字列をウィンドウの中央付近に表示する
・プログラムの終了条件を入れるなど,自分なりのアレンジを加えても良い
ということで書いてみて、コンパイルが通るところまではいったのですが、実行するとコアダンプが起きます。
授業のスライドを何度も見返して何時間も格闘したのですが、結局分かりませんでした...。
発生している問題・エラーメッセージ
$ gcc kadai1.c -lSDL2 -lSDL2_gfx -lSDL2_ttf -lSDL2_image -lSDL2_mixer
$ ./a.out
Segmentation fault (コアダンプ)
該当のソースコード<kadai1.c>(無駄にincludeしていると思います、すみません。)
#include <stdio.h> #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <SDL2/SDL_mixer.h> #include <SDL2/SDL_ttf.h> #include <SDL2/SDL2_gfxPrimitives.h> #include <SDL2/SDL_net.h> int main(int argc, char *argv[]){ int x = 500; int y = 500;//マウスの座標を格納 int a = 0; //SDL_MOUSEBUTTONUP施行のタイミングの制御 int b = 0; //Good job!!描画の制御 char s[64];//マウス座標を格納するための文字列 char f[64];//起動時にマウス座標を表示するための文字列 SDL_Window *window ; // ウィンドウのデータを格納する構造体 SDL_Renderer *renderer; //最初に丸と四角を表示させておくためのレンダラー SDL_Event event; // SDLによるイベントを検知するための構造体 SDL_Event quit_event = {SDL_QUIT}; // 特定のイベント名を格納 SDL_Surface *f_strings; // サーフェイス(メインメモリ上の描画データ)を格納する構造体 SDL_Surface *strings; // サーフェイス(メインメモリ上の描画データ)を格納する構造体 SDL_Texture *f_texture; // テクスチャ(VRAM上の描画データ)を格納する構造体 SDL_Texture *texture; // テクスチャ(VRAM上の描画データ)を格納する構造体 TTF_Font* font; // TrueTypeフォントデータを格納する構造体 SDL_Color white = {0x00, 0x00, 0x00, 0xFF}; // フォントの色を指定するための構造体(白色) SDL_Color blue = {0x00, 0x00, 0xFF, 0xFF}; // フォントの色を指定するための構造体(青色) if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { printf("failed to initialize SDL.\n"); exit(-1); }// SDL初期化(初期化失敗の場合は終了) // ウィンドウ生成・表示 window = SDL_CreateWindow("Press [Esc] to exit",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,960,720,0); if(window == NULL){ printf("Failed to create window.\n"); exit(-1); } sprintf(f,"x,y=%d,%d",0,0); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); // 拡大縮小を滑らかにする(線形フィルタで) TTF_Init(); // TrueTypeフォントを用いるための初期化 font = TTF_OpenFont("./migu.ttf", 24); // fonts-japanese-gothicフォントを12ポイントで使用(読み込み) // レンダラー作成 renderer = SDL_CreateRenderer(window, -1, 0); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 0);//生成したRCに描画色として白を設定 SDL_RenderClear(renderer);//白で塗りつぶす rectangleColor(renderer, 600, 400, 850, 600, 0xff0000ff);// 生成したウィンドウに対してレンダリングコンテキスト(RC)を生成 filledCircleColor(renderer, x, y, 25, 0xff0000ff); strings = TTF_RenderUTF8_Blended(font, "x,y = 0,0", white);//描画文字の作成と格納 texture = SDL_CreateTextureFromSurface(renderer, strings);//サーフェイスからテクスチャへ変換 // 文字列描画(表示)のための設定 SDL_Rect src_rect = {0, 0, strings->w, strings->h};//コピー元文字列の領域(x, y, w, h)(strings->wとstrings->hにはそれぞれ文字列の横幅と高さが格納される) SDL_Rect dst_rect = {10, 0, 100, 50};//文字列のコピー先の座標と領域(x, y, w, h) SDL_RenderCopy(renderer, texture, &src_rect, &dst_rect); // テクスチャをRCにコピー(設定のサイズで) SDL_RenderPresent(renderer); // 描画データを表示 while(1){ // イベントを取得したなら if(SDL_PollEvent(&event)){ // イベントの種類ごとに処理 switch (event.type) { case SDL_MOUSEMOTION: // マウスが移動した時 printf("Mouse moved by %d,%d to (%d,%d)\n", event.motion.xrel, event.motion.yrel, event.motion.x, event.motion.y); // マウスの座標を表示 sprintf(s,"x,y=%d,%d",event.motion.x, event.motion.y); strings = TTF_RenderUTF8_Blended(font, s, white); // 描画文字の作成と格納 texture = SDL_CreateTextureFromSurface(renderer, strings); // サーフェイス(文字列の描画データが格納されている)からRCのテクスチャを生成(サーフェイスからテクスチャへ変換) SDL_Rect src_rect = {0, 0, strings->w, strings->h}; // コピー元文字列の領域 SDL_RenderCopy(renderer, texture, &src_rect, &dst_rect); // テクスチャをRCにコピー(設定のサイズで) SDL_RenderPresent(renderer); // 描画データを表示 break; case SDL_MOUSEBUTTONDOWN: // マウスボタンが押された時 printf("Mouse button %d pressed at (%d,%d)\n",event.button.button, event.button.x, event.button.y);// 押されたマウスのボタン等を表示 if(event.button.x - x <= 25 && event.button.y <=25 && event.button.x >= -25 && event.button.y >= -25){ a = 1; break; } break; case SDL_MOUSEBUTTONUP: if(a==1){ //マウスボタンが離された時 printf("Mouse button up at (%d,%d)\n", event.button.x, event.button.y);//マウスを離した地点 filledCircleColor(renderer, event.button.x, event.button.y, 50, 0xff0000ff); x = event.button.x; y = event.button.y; a = 0; SDL_SetRenderDrawColor(renderer, 255, 255, 255, 0); // 生成したRCに描画色として白を設定 SDL_RenderClear(renderer); // 生成したRCを白でクリア=塗りつぶす(ただし,メモリに描画データを反映させただけなので,画面には表示されない) rectangleColor(renderer,600,400,850,600,0xff0000ff); if ( event.motion.x <= 850 && event.motion.x >= 600 && event.motion.y <= 600 && event.motion.y >= 400 ){ f_strings = TTF_RenderUTF8_Blended(font, "Good job!!", blue); // 描画文字の作成と格納(白色のfonts-japanese-gothicフォントで,文字列をサーフェイスに描画=データとして格納) f_texture = SDL_CreateTextureFromSurface(renderer, f_strings); // サーフェイス(文字列の描画データが格納されている)からRCのテクスチャを生成(サーフェイスからテクスチャへ変換) // 文字列描画(表示)のための設定 SDL_Rect src_rect = {0, 0, f_strings->w, f_strings->h}; // コピー元文字列の領域 SDL_Rect dst_rect = {410, 320, 100, 50}; // 文字列のコピー先の座標と領域(x, y, w, h) SDL_RenderCopy(renderer, f_texture, &src_rect, &dst_rect); // テクスチャをRCにコピー(設定のサイズで) SDL_RenderPresent(renderer); // 描画データを表示 b = 1; break; } b = 0; } break; case SDL_KEYDOWN: // キーボードのキーが押された時 switch(event.key.keysym.sym){ case SDLK_ESCAPE: // Escキーが押された時 printf("ESCAPE key -> EXIT.\n"); SDL_Quit(); exit(0); break; } break; case SDL_QUIT:// SDLの利用を終了する時(イベントキューにSDL_QUITイベントが追加された時) TTF_CloseFont(font); // 使用したフォントを閉じる TTF_Quit(); // TTFライブラリの使用を終了 SDL_FreeSurface(strings); // サーフェイスの解放 SDL_DestroyRenderer(renderer);// RCの破棄(解放) SDL_DestroyWindow(window);// 生成したウィンドウの破棄(消去) SDL_Quit(); exit(0); break; } //レンダラー再描画 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 0); // 生成したRCに描画色として白を設定 SDL_RenderClear(renderer); // 生成したRCを白でクリア=塗りつぶす(ただし,メモリに描画データを反映させただけなので,画面には表示されない) strings = TTF_RenderUTF8_Blended(font, s, white); // 描画文字の作成と格納 texture = SDL_CreateTextureFromSurface(renderer, strings); //サーフェイスからテクスチャへ変換 SDL_Rect src_rect = {0, 0, strings->w, strings->h}; // コピー元文字列の領域(x, y, w, h) SDL_Rect dst_rect = {10, 0, 100, 50}; // 文字列のコピー先の座標と領域(x, y, w, h) SDL_RenderCopy(renderer, texture, &src_rect, &dst_rect); // テクスチャをRCにコピー(設定のサイズで) filledCircleColor(renderer,x,y,25,0xff0000ff); rectangleColor(renderer,600,400,850,600,0xff0000ff); if( b==1 ){ SDL_Rect dst_rect = {410, 320, 100, 50}; // 文字列のコピー先の座標と領域(x, y, w, h) SDL_RenderCopy(renderer, f_texture, &src_rect, &dst_rect); // テクスチャをRCにコピー(設定のサイズで) } SDL_RenderPresent(renderer); // 描画データを表示 } } return 0; }
試したこと
仮想LINUX環境で、gdbコマンドでデバッグしてコアダンプの原因を調べるという方法も、ネットで調べながら試したのですがエラーが起こっている肝心の関数名が「??」と表示されていて、分かりませんでした。
ポインタを多く使っているので、そこを間違えているのかなと思いましたが、私の目では問題を見つけられませんでした。(実力不足という意味で)
助けてください...。
補足情報
PCはWindowsですが、VMwareでUbuntoの仮想環境を使っています。
プログラムではSDLライブラリも使います。