C言語で文字列の領域をmallocで確保する際に気を付けること
はじめに
こんにちは、ばりです。最近C言語の復習をしてます(といってもVisual Studio2022で.cppに書き込んでる)。C言語といえば文字列はchar型の配列で扱うわけですが、やっぱり動的に配列サイズを確保したいですよね。char[100] str;みたいにデカ配列用いすればええやろ!みたいなのあんまりスマートじゃないですし…。と思ってmallocを使って文字列確保をしようとしたら、ドツボにハマって結局6時間くらい溶かしました。原因がかなり初歩的な内容だったので戒めを込めて残しておきます。
結論
文字を確保する際は終端文字の領域をちゃんと確保しよう!!
// ヘッダファイルは省略 int main(void) { char str[] = "hogehoge"; char strSize = (strlen(str) + 1); // ここで終端文字'\0'の分までサイズを設定する // 文字列のサイズ分のメモリを確保 char* hoge = (char*)malloc(sizeof(char)* strSize); // 文字列の内容をコピー strcpy_s(hoge, sizeof(char) * strSize, str); // **************** // いろいろな処理 // **************** // メモリを解放 if (hoge) { free(hoge); hoge = NULL; } return 0; }
(文字列コピーして終わりって何がしたいんだって話ですけど、もともとは引数の文字列を取得するみたいなコードでした)
C言語では文字列の最後に\0を用意するなんて当たり前なんですけど、これに気づかず頭を抱えていたわけですね…。
ついでに、終端文字の存在に途中で気づいてコードをいじったことが余計にドツボにハマるきっかけになりました。 6時間も溶かした詳細を知りたい方は以下もどうぞ。
なにをしていたか
int main(void) { char str[] = "hogehoge"; char strSize = strlen(str); char* hoge = (char*)malloc(sizeof(char)* strSize); // 終端文字を考慮せずにメモリを確保 strcpy_s(hoge, sizeof(char) * (strSize + 1), str); // なぜかここでは終端文字を考慮してますよって噓をついたコード(?????) // **************** // いろいろな処理 // **************** if (hoge) { free(hoge); // エラー hoge = NULL; } return 0; }
最初はstrSizeをそのまま文字列サイズでおいてたわけです。
これをすると実行時にエラーを吐きます。

「アプリケーションが、ヒープバッファが終わった後の部分にも書き込もうとしてるぜ!」
char* hoge は終端文字の情報を持っていないので、まあ当然っちゃ当然ですね。
ただ、確保したメモリ以上の内容を書き込もうとしてるはずのstrcpy_sの箇所ではエラーは出てないんですよね。
エラーが出力されるのはfree(hoge)の部分。
僕がstrcpy_sの引数で嘘をついたので、「ほなええか!」とエラー吐かず通過してしまったぽい。
strcpy_sは書き込み先のBufferが明らかに足りてなかったらエラーはいてくれたっていいじゃないか
なのでメモリ解放の際に終端文字を読み込むまで処理を進めていこうとしたら、終端文字よりも先に確保部分が終わってしまったため、「解放したい部分のメモリ、自分の土地の外にあるんだけど!」のエラーですね(多分)。
しかし、strcpy_sの直後にprintf("%s", hoge)するとちゃんとhogehogeが出力されます。
なので「あれ?文字列はちゃんと格納できてるよな…」となって原因特定に時間がかかってしまったみたいですね(他人事)。
仮に、以下のように
int main(void) { char str[] = "hogehoge"; char strSize = strlen(str); char* hoge = (char*)malloc(sizeof(char)* strSize); strcpy_s(hoge, sizeof(char) * strSize, str); // 嘘をついていない正しいサイズを伝えているコード // エラー // **************** // いろいろな処理 // **************** if (hoge) { free(hoge); hoge = NULL; } return 0; }
とすると

「バッファが小さすぎるぜ!」
と、ちゃんとstrcpy_sの部分がエラーを吐いてくれます。
なので今回のポイントは
終端文字の知識が浅かった上に中途半端に変数を変えて試行錯誤したせいでさらに複雑化した
の部分かなと思います。
反省
下手に原因がよくわからないままいろいろな値を試してみる、のような試行錯誤はよくないなぁと実感。 まず何が原因でエラーが起こっているかを吟味して、そのうえで解決のためのコードを書くことを意識しようと思いました(小並感)。
failed to solve with frontend dockerfile.v0: failed to read dockerfile: ~~~: no such file or directoryが解決できた話
症状
フロントエンド、バックエンド、データベースの3つで構成されるWebアプリケーションのdocker-compose.ymlからdocker-compose upしようとしたら データベースのimage(mysql:8.0)のビルドのタイミングでタイトルのエラーが出た
自分の環境でビルドできなくて他人の環境だとビルドできる状況
なんのためにDocker使ってんねん、とわけがわからない状態だった(Docker初心者並感想)
ちなみに、フロントとバックのimageはDockerfileで作成したが、データベースはimageをDockerHubから落としている。
Chromeで検索かけても、「Dockerfileの命名が間違ってました〜」みたいな記事しかヒットしなくて、そもそもDockerfileないねん!って1人でキレてた
解決策
docker pull mysql:8.0
上記をターミナルで入力することでimageをローカルに落としてから再度docker-compose upをする。
これだけで正常に動くようになった
感想
どうやらdocker-composeするときは公式イメージはちゃんと事前にpullしないといけないらしい
docker-compose pull
これでもいいっぽい。友達のPCには既にmysql:8.0のイメージがあったからうまく行ってたっぽいね
なんとなく使ってると、こういう問題に遭遇した時に解決に苦労することがよくわかりましたね…
ゲーミングPCの購入を決め、モニター選びに困っている人に届けるゲームモニターの選び方
はじめに
始めてゲーミングPCを買う人が次に困るのはモニター選びではないでしょうか。
この記事は、「一言でモニターと言ってもいろいろあるしどれを選べばいいの…?」って人に向けた記事です(あくまで、初心者向けの記事なので細かいこだわりには対応してません、たぶん)。
結論
解像度1920×1080、リフレッシュレート144Hz(120Hz)のTNモニターがオススメ
自分は、一般的なFHD(1920×1080)の解像度と一般的な60Hzの倍の120Hzのリフレッシュレート、そして比較的安価なTN液晶で作られたモニターが初心者にはちょうどいいと思ってます。というのも、もっとグレードの高いものが欲しければその時に追加で買えばいいと思ってるんですよね。モニターはPCに複数つなげられるから、正直なんぼあっても困らないし…(当社比)。
詳しく知りたい!って人は以下も見てもらえたら少しは参考になるかなと思います。
以下に具体的なポイントを書いていきます。
大まかな注目ポイント
ゲームをする上で特に大事そうなポイントをまずまとめてみました。
解像度
解像度とは、画面を表すうえでの点(ドット)の数です。横の数と縦の数の掛け算で表されます。値が大きければ大きいほど画面が細かくきれいに映ります。
解像度の選択候補に挙がるのは主に以下の3種類だと思います。
- FHD(1920×1080)
- WQHD(2560×1440)
- 4K(3940×2160)
普段使い、とりわけ用途がゲームのみ、ということであればFHDで問題ないです。
WQHDおよび4Kは、より美麗なグラフィックが欲しい!って人はいいかもしれないけど…ゲーム用途としては初心者が初めから必要かといわれると微妙です。
もし、ゲーム以外にがっつりとプログラミングをしたり動画編集をしたりするというような人は検討してみてもいいかもしれません。
リフレッシュレート
リフレッシュレートとは、1秒間の画面の更新回数です。ヘルツ(Hz)という単位で表します。リフレッシュレートは、大きければ大きいほど画面が頻繁に切り替わるため画面がぬるぬると動きます。
リフレッシュレートの候補は主に以下の3種類です。
- 60Hz
- 144Hz
- 240Hz
60HZはよくあるモニターの解像度です。対してこれを144Hzにすると画面が一気になめらかになります。これは実際に見てみないとわからないのですが、マジでぬるぬるです。感動すら覚えます。マジで。144Hzから240Hzでももちろん変化するのですが、まずは144Hzを体験してみるといいと思います。
補足
本記事では解像度を高くするよりリフレッシュレートを高くすることをお勧めしています。理由としては、FPSを始めとしたPvPゲームではリフレッシュレートが高ければ高いほど優位に立つことができるからです(画面上での相手の位置の更新頻度が60Hzと144Hzで倍以上違うため)。なので、逆に言ってしまえばPvPをしないのであれば高解像度のモニターを検討してもいいかもしれません。
しかし、高解像度の方が値段は高くなる傾向がある(気がする)ので注意してください。
モニターサイズ
モニターサイズとは、その名の通りモニターの大きさです。インチで表します(1インチ=2.54cm)。
モニターはでかけりゃいいというものでもなく、本記事でオススメしているFHDのモニターであれば23インチ~28インチのモニターがオススメです。
パネルの種類
パネルの種類は大きく分けて4種類あります。
TNパネル
メリット:応答速度が速い、とても安価
デメリット:視野角が狭い、実際の色と発色の間にずれが生じる場合がある
今回オススメのTNパネルは単刀直入に言うとコスパ重視のパネルです。視野角に関しては正面から使う分には問題ありませんし、発色に関しては普通に使っている分にはあまり気になりません(あくまで個人の感想です)。
IPSパネル
メリット:実際の色と発色の間のずれが一番少ない、視野角が広い、全体的に優秀
デメリット:高価
VAパネル
メリット:コントラストがきれい(らしい)、視野角が広い
デメリット:実際の色と発色の間にずれが生じる場合がある、応答速度が遅め
有機EL
メリット:きれい
デメリット:高い
特にこだわらなければTNでいいと思ってます。でも、それ以外のパネルのモニターを使うと、TNには戻れなくなるという話もちょくちょくききます。まあ最初はTNでいいでしょ(適当)
更にこだわるポイント
パネルの説明で感じたかもしれませんが、めんどくなってきたのでここからは適当に書きます。
その気があれば修正します(修正ができるのか知らないけど)
モニターと縁の間の幅(ベゼル幅)
コスパ最強を謳うモニターはだいたい縁が広かったりします。
モニター自体の見栄えを気にする人や、デュアルディスプレイを検討している人は注意して選ぶといいかもしれません。
入力端子
HDMI、DisplayPortがあれば基本的に何でもいいです。VGAがあったりすると比較的古めのディスプレイな気がしてます(偏見)。
加えてType-Cの端子がある接続モニターだと、ゲーミングPCだけでなくノートPC(特にMacBook)も簡単に接続できるようになります。
また、モノによってはUSBハブの代わりをしてくれるモニターもあるので便利さを求めるなら一考してみてはどうでしょうか
応答速度
5ms以下ならおk
終わりに
以上で終わります。初めての記事なので駄文だと思いますが、特別引用もしてないし確認もめんどくさいのでこれで終わります。
ここまで見てくださってありがとうございました。
videoタグのレスポンシブ対応でハマってしまった
こんにちは、実況動画の投稿をしてみたいけどひたすら腰が重いばりです。
今や様々な端末でWEBサイトがのぞかれる時代ですね
僕もWEBサイトを作っていて、その中で動画のレスポンシブ対応をvideoタグにて行おうとした際にちょっとした謎の使用にぶち当たってハマってしまったので備忘録的に残しておきます。
不具合内容
videoタグ内に横幅(width="**%"といった具合)を指定することでレスポンシブ対応をしようとしたところ、動画の上下に謎の余白が出現してしまった。
確認環境
解決方法
widthのほかに高さ(height)も指定してやる。これだけです。
ちなみにautoだとだめでした。heightの値は%指定をいくつにしても動画の大きさ自体に変化はありませんでした。
ぶっちゃけ経験不足によるミスだとは思いますが、最初に見つけた時にめちゃめちゃドツボにはまったのと、同じことに困る人はおそらくいるだろう!(希望的観測)ということでせっかくなので記事にしてみました。
それでは