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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

SDL (Simple DirectMedia Layer)

SDL (Simple DirectMedia Layer)は、C言語で記述されたクロスプラットフォームのマルチメディアライブラリです。画像や音などを 統一してアクセスするためのAPIを提供。LinuxやWindows、各種MacOSなどを公式にサポートしています。

Q&A

3回答

2616閲覧

SDLの基礎的なプログラムで、コアダンプの原因が分かりません

loshelon

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

SDL (Simple DirectMedia Layer)

SDL (Simple DirectMedia Layer)は、C言語で記述されたクロスプラットフォームのマルチメディアライブラリです。画像や音などを 統一してアクセスするためのAPIを提供。LinuxやWindows、各種MacOSなどを公式にサポートしています。

0グッド

0クリップ

投稿2020/07/28 05:53

編集2020/07/28 07:36

前提・実現したいこと

誰か分かる方、助けてください...!
レポートで、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ライブラリも使います。

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

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

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

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

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

y_waiwai

2020/07/28 06:02

このままではコードが読めないので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
loshelon

2020/07/28 06:06

ありがとうございます! 初めてなのでわかりませんでした...(笑)
guest

回答3

0

SDLの事は知らないので、他の人に任せるとして。

仮想LINUX環境で、gdbコマンドでデバッグしてコアダンプの原因を調べるという方法も、ネットで調べながら試したのですがエラーが起こっている肝心の関数名が「??」と表示されていて、分かりませんでした。

gccで「-g」オプションを指定してビルドすると、デバッグ情報が付加されます。

…て、「-g3」なんてオプションもあるんですね。知らなかった。
なんでしたら、そちらも試してみてください。

投稿2020/07/28 11:23

katsuko

総合スコア3469

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

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

0

// レンダラー作成

を行うよりも前に,rendererに対する処理(SDL_RenderSetLogicalSize)を記述しているのが問題ではないかと.

rendererが初期化もされてないので,何が起こるか…)

投稿2020/07/28 06:46

fana

総合スコア11656

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

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

loshelon

2020/07/28 07:42

確かに順番がおかしいですね! でもそれで、レンダラーを作成した後のいろんな場所に入れて試したんですけど、やっぱりコアダンプします。最終的にこのSDL_RenderSetLogicalSize自体を消してやってみたんですけど、まだコアダンプしました。...ほかにもおかしいところがありますかね...
fana

2020/07/28 08:15

どうにかしてデバッグしてください,としか. ログ出力を各所に仕込むとか,何らかの要素単位でコメントアウトするとかして,どこで問題が起きるのかを突き止めてください.
fana

2020/07/28 08:20

(一応タグにCだけじゃなくC++もついてるようだし)コードをCじゃなくてC++だということにして,変数を本当に必要な箇所で定義する形にすれば,このような順番がおかしいコード自体を書けなくなる(コンパイル通らなくなる)と思う.
fana

2020/07/28 08:22

コード内にprintf()が書かれてますが,printf()ってどこかにちゃんと出力されるんでしょうか? もし出力できるなら,いわゆる「printfデバッグ」で死亡箇所を突き止めればよいかと.
loshelon

2020/07/28 15:57

ありがとうございます...! とりあえずwhile文をすべてコメントアウトして、ウィンドウだけでもちゃんと表示されるのか試したんですけど、だめでした。そこで、fanaさんがおっしゃったようにさらにコメントアウトしていくと、56行目の「strings=」のところから62行目の「SDL_RenderCopy」のところまでのこの5つのコードのどれかでエラーが起こっていることまで突き止めましたが、どれだけ調べても間違いがわかりません。パソコンに問題があるパターンもあるんでしょうか?
fana

2020/07/29 01:24

> どれだけ調べても と言われても何をどう調べているのか謎ですし, こちらは実際にそのコードを動作させているわけでもないので,ずばっと「これでしょ」とは言えないんですよね. 【コードを眺めた限りで「間違いがない」状態だけども実行時に問題が起きている】のであれば,私なら処理の失敗を疑いますが,そこらへんは「調べて」いますか? 質問のコードにてSDL_CreateWindowの戻り値のチェックを書いているように,他の関数呼び出しの結果に関してもエラーなり失敗なりを示す結果が返ってきていないかをチェックするコードを追加して, どこかで失敗になっているようなら,そこでエラー情報を取得する手段(TTF_GetErrorだのSDL_GetErrorだのいう関数があるみたい)を用いてみればヒントが得られるかもしれません. 外野からコードを見た感じでは,例えば, > font = TTF_OpenFont("./migu.ttf", 24); なんかは,いかにも「失敗しやすそうな」処理に見えます.
guest

0

SDL_Renderer *renderer; //最初に丸と四角を表示させておくためのレンダラー

...
SDL_RenderSetLogicalSize(renderer, 960, 720); // デバイスに依存しない分解能を設定

これは使い方が間違ってます

SDL_Renderer renderer;
...
SDL_RenderSetLogicalSize(&renderer, 960, 720);

と、するべきものです。
各関数の仕様/定義を確認しましょう

#他の格納域も同じ

投稿2020/07/28 06:09

編集2020/07/28 06:11
y_waiwai

総合スコア87774

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

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

fana

2020/07/28 06:41

低評価理由:回答内容は違う. レンダリングコンテキストは > renderer = SDL_CreateRenderer(window, -1, 0); として,ライブラリによって生成してもらって,戻り値をポインタでもらう形なので, > SDL_Renderer *renderer; で合っていると思う.
y_waiwai

2020/07/28 06:42

ライブラリに生成してもらって、未初期化のポインタアドレスに格納するんでしょうか? それこそ不正アクセスとなりますよ。
y_waiwai

2020/07/28 06:45

ああ、生成する前に格納してますわなw
loshelon

2020/07/28 07:47

すみません、順番がおかしかったですね...。 でも直してもコアダンプしました。まだほかにおかしい所があるんでしょうか。
y_waiwai

2020/07/28 07:49

同様に、所得する前に使ってるような所あるんでは。 よく探してみよう
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問