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

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

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

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

SDL (Simple DirectMedia Layer)

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

Q&A

解決済

2回答

3638閲覧

SDL2で文字の表示ができない

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

SDL (Simple DirectMedia Layer)

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

0グッド

0クリップ

投稿2019/06/03 09:20

前提・実現したいこと

SDL2を使って、画面に文字を表示するプログラムを作っています。

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

コンパイルはできたのですが、起動するとSegmentation fault:11と表示され起動できません。
エラーメッセージはこちらに書いてあります。

該当のソースコード

C

1#include "SDL2/SDL.h" 2#include "SDL2/SDL_ttf.h" 3 4int main(int argc, const char *argv[]) 5{ 6 SDL_Window *Window; 7 SDL_Surface *image; 8 SDL_Rect rect, rect_pos; 9 SDL_Event event; 10 SDL_Color white = {255, 255, 255}; 11 TTF_Font *font; 12 SDL_Renderer *renderer; 13 SDL_Texture *texture; 14 int isFinish = 0; 15 16 SDL_Init(SDL_INIT_EVERYTHING); 17 TTF_Init(); 18 19 renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED); 20 Window = SDL_CreateWindow("Font", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); 21 font = TTF_OpenFont("rounded-x-mplus-1c-black.ttf", 24); 22 23 image = TTF_RenderUTF8_Blended(font, "あいうえお", white); 24 texture = SDL_CreateTextureFromSurface(renderer, image); 25 26 SDL_FreeSurface(image); 27 28 rect.x = 0; 29 rect.y = 0; 30 rect.w = image->w; 31 rect.h = image->h; 32 33 rect_pos.x = 0; 34 rect_pos.y = 0; 35 36 SDL_RenderClear(renderer); 37 SDL_RenderCopy(renderer, texture, NULL, &rect); 38 SDL_RenderPresent(renderer); 39 40 while (isFinish == 0) 41 { 42 while (SDL_PollEvent(&event)) 43 { 44 switch (event.type) 45 { 46 case SDL_KEYDOWN: 47 switch (event.key.keysym.sym) 48 { 49 case SDLK_ESCAPE: 50 isFinish = 1; 51 } 52 } 53 } 54 55 SDL_Delay(1); 56 } 57 58 SDL_DestroyRenderer(renderer); 59 SDL_DestroyTexture(texture); 60 SDL_DestroyWindow(Window); 61 62 SDL_Quit(); 63 64 return 0; 65}

試したこと

rendererやtextureを使用せず、surfaceで表示することも試してみました。こちらはウインドウは表示されましたが、文字が表示されていません。

C

1#include "SDL2/SDL.h" 2#include "SDL2/SDL_ttf.h" 3 4int main(int argc, const char *argv[]) 5{ 6 SDL_Window *Window; 7 SDL_Surface *image, *screen; 8 SDL_Rect rect, rect_pos; 9 SDL_Event event; 10 SDL_Color white = {255, 255, 255}; 11 TTF_Font *font; 12 int isFinish = 0; 13 14 SDL_Init(SDL_INIT_EVERYTHING); 15 TTF_Init(); 16 17 Window = SDL_CreateWindow("Font", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); 18 font = TTF_OpenFont("rounded-x-mplus-1c-black.ttf", 24); 19 20 image = TTF_RenderUTF8_Blended(font, "あいうえお", white); 21 22 rect.x = 0; 23 rect.y = 0; 24 rect.w = image->w; 25 rect.h = image->h; 26 27 rect_pos.x = 0; 28 rect_pos.y = 0; 29 30 SDL_BlitSurface(image, NULL, screen, &rect_pos); 31 SDL_UpdateWindowSurface(Window); 32 SDL_FreeSurface(image); 33 34 while (isFinish == 0) 35 { 36 while (SDL_PollEvent(&event)) 37 { 38 switch (event.type) 39 { 40 case SDL_KEYDOWN: 41 switch (event.key.keysym.sym) 42 { 43 case SDLK_ESCAPE: 44 isFinish = 1; 45 } 46 } 47 } 48 49 SDL_Delay(1); 50 } 51 52 SDL_DestroyWindow(Window); 53 54 SDL_Quit(); 55 56 return 0; 57}

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

gccでコンパイルしています

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

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

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

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

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

guest

回答2

0

SDL_CreateRendererの第1引数はSDL_Window*ですが、
SDL_CreateWindowで値を入れる前なので中身は不定です。

Segmentation faultの原因はココ

cpp

1 renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED); 2 Window = SDL_CreateWindow("Font", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);

TTF_OpenFontでフルパスを指定しないとカレントフォルダ(実行ファイルと同じフォルダ)を参照するので、標準でインストールされているフォントだからといって省くとエラーになると思われる。
この場合、実行ファイルと同じフォルダにmeiryo.ttcが無いとTTF_GetErrorCouldn't open meiryo.ttcというメッセージを返す。

ここはちゃんとエラーチェックをした方が良いと思う。

あと、TTF_RenderUTF8_Blended(font, "あいうえお", white);の部分
ソースコードがUTF-8で保存されていないと文字化けする
ほかは知らないけどWindowsでVisual Studioを使う場合はu8"あいうえお"とした方が良い。

cpp

1 TTF_Font *font = TTF_OpenFont("meiryo.ttc", 24); 2 if (font == NULL) 3 { 4 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", TTF_GetError()); 5 return EXIT_FAILURE; 6 }

imageから値を取り出す前にSDL_FreeSurfaceで開放処理をしてしまっているので、image->wimage->hの値は不定です。

こちらの環境ではwhに負の値が入っていて文字が描画されませんでした。

cpp

1 SDL_FreeSurface(image); 2 3 rect.x = 0; 4 rect.y = 0; 5 rect.w = image->w; 6 rect.h = image->h;

SDL_RenderClearSDL_RenderCopySDL_RenderPresentの一連の描画処理がループ前に行われています。
キー入力で動かしたりする処理が入って無いので問題はないかもしれませんが…。

後、switch case文ですがbreakdefaultは省かずにちゃんと書いたほうが良いです。
思わぬバグの元になりますので。

cpp

1#include <SDL.h> 2#include <SDL_ttf.h> 3 4int main(int argc, char *argv[]) 5{ 6  SDL_Rect rect; 7 SDL_Event event; 8 SDL_Color white = {255, 255, 255}; 9 int isFinish = 0; 10 11 SDL_Init(SDL_INIT_EVERYTHING); 12 TTF_Init(); 13 14 // ウィンドウを生成してからレンダラーを生成する 15 SDL_Window *Window = SDL_CreateWindow("Font", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); 16 SDL_Renderer *renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED); 17 18 TTF_Font *font = TTF_OpenFont("meiryo.ttc", 24); 19 if (font == NULL) 20 { 21 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", TTF_GetError()); 22 return EXIT_FAILURE; 23 } 24 25 SDL_Surface *image = TTF_RenderUTF8_Blended(font, u8"あいうえお", white); 26 SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, image); 27 28 // rectにimageの幅と高さを入れてからサーフェスを開放する 29 rect.x = 0; 30 rect.y = 0; 31 rect.w = image->w; 32 rect.h = image->h; 33 34 SDL_FreeSurface(image); 35 36 while (isFinish == 0) 37 { 38 while (SDL_PollEvent(&event)) 39 { 40 switch (event.type) 41 { 42 case SDL_KEYDOWN: 43 switch (event.key.keysym.sym) 44 { 45 case SDLK_ESCAPE: 46 isFinish = 1; 47 // breakとdefaultは思わぬバグを生むため省かずに書いたほうが良いと思う 48 break; 49 default: 50 break; 51 } 52 break; 53 case SDL_QUIT: 54 isFinish = 1; 55 break; 56 default: 57 break; 58 } 59 } 60 // 描画処理はループ内で行う 61 SDL_RenderClear(renderer); 62 SDL_RenderCopy(renderer, texture, NULL, &rect); 63 SDL_RenderPresent(renderer); 64 } 65 66 // 開放処理は生成とは逆の順で行う(texture > renderer > Window) 67 SDL_DestroyTexture(texture); 68 SDL_DestroyRenderer(renderer); 69 SDL_DestroyWindow(Window); 70 71 SDL_Quit(); 72 73 return 0; 74} 75

投稿2019/06/03 12:47

編集2019/06/03 13:13
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2019/06/03 13:52

回答ありがとうございます。 自分では全然気づけなかったので、その辺まだまだ甘いなと思いました。 これからは意識していこうと思います。
guest

0

ベストアンサー

SDL詳しいわけではないけど、まずSegmentation Faultが起きている箇所は、おそらく下記。

C

1renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED);

原因はポインタ変数Windowが初期化されていないのに使っているから。
※アドレスがゴミ値で、アクセス不可なアドレスに行こうとして落ちてる。

SDL_CreateRenderer()のリファレンスへのリンクを貼っておくので、そこにあるサンプルに目を通してみて。
SDL_CreateRendererのリファレンス

第1引数で指定するウィンドウのインスタンスに対してレンダラーを持たせるようなので、まずはウィンドウのインスタンスを作成して、それをSDL_CreateRenderer()の第1引数で指定すればいいんじゃないかな。

とりあえず、パッと見で分かるのはこれくらい。

投稿2019/06/03 10:00

archiver

総合スコア1557

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

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

退会済みユーザー

退会済みユーザー

2019/06/03 13:50

回答ありがとうございます。解決しました。 完全に盲点でした...
archiver

2019/06/03 14:22

デバッガ使ったことありますか? デバッガ(gccを使っているようなので、ここではgdb)使うと、coreファイルから落ちた場所の特定とかができるので、使えるようになった方が、後々問題解決に繋がりやすくなりますよ。 #まあ、実行ファイルは-gオプションを付けてコンパイルする必要がありますが
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問