C++
 Computer >> コンピューター >  >> プログラミング >> C++

【C言語】getsやputsでアロー演算子(->)が使えないのはなぜ?未初期化ポインタの落とし穴と正しい書き方

未初期化のポインタに対して、直接ユーザー入力を読み込むことはできません。ポインタはあくまで「メモリ上のアドレスを格納する変数」であり、どこも指していない状態のまま -> 演算子でメンバにアクセスしようとすると、未定義動作となりプログラムがクラッシュする可能性があります。

正しい手順は次のとおりです。まず構造体型の実体となる変数を宣言し、その変数のアドレスをポインタに代入します。こうしてポインタが有効なメモリ領域を指すようになって初めて、アロー演算子を使って構造体のメンバに安全にアクセスできるようになります。

コード例

#include <stdio.h>

struct example {
    char name[20];
};

main() {
    struct example *ptr;   /* ポインタの宣言(まだどこも指していない) */
    struct example e;      /* 構造体の実体を確保 */

    puts("enter name");
    gets(e.name);          /* 実体のメンバに入力を受け取る */
    ptr = &e;              /* 実体のアドレスをポインタに代入 */
    puts(ptr->name);       /* アロー演算子でメンバを出力 */
}

ポイント解説

  • struct example *ptr; の時点では、ptr は不定のアドレスを持つ「未初期化」の状態です。
  • ここで gets(ptr->name) としてしまうと、無効なアドレスへの書き込みとなり、動作は一切保証されません。
  • ptr = &e; で有効な構造体変数 e のアドレスを代入してからアクセスするのが正しい流れです。

実行結果

上記コードを実行すると、典型的には次のような出力になります。

enter name
Disha        ← キーボードから入力した名前
Disha        ← ptr->name の内容が出力される

補足:gets() を使う際の注意点

gets() は入力サイズの制限ができずバッファオーバーフローの危険があるため、C11規格で標準ライブラリから削除されました。実際の開発では、次のように fgets() を使うことが強く推奨されます。

fgets(e.name, sizeof(e.name), stdin);
  1. Safariでプライベートブラウジングを使う理由と設定方法を徹底解説

    macOSの標準ブラウザであるSafariは、近年のWebブラウザと同様に高度に進化しており、高いセキュリティ性を備え、複数のタブも快適に同時処理できます。さらに、Safariには「プライベートブラウジング」モードが搭載されており、閲覧履歴を残さずにこっそりとWebを利用することが可能です。 MacのSafariでプライベートブラウジングを活用する理由は数多くあります。この記事では、プライベートブラウジングとは何か、Macでどのように使えば安全で機密性の高いブラウジング体験を実現できるのかを詳しく解説します。 サイバー犯罪が増加している現代において、プライベートブラウジングは個人情報を守り、悪

  2. 個人用リマインダーアプリの使い方と活用すべき理由

    「えっ、まさか!完全に忘れてた!」 この言葉、私が一日に何度も口にするフレーズです。物忘れが多いからですが、脳や健康に問題があるわけではなく、現代社会があまりにもスピーディーに動いていることが原因だと気づきました。やることは山ほどあり、会うべき人もたくさんいて、Netflixで観たい作品も次々と追加される――こんな環境では、何かを忘れてしまうのも無理はありません。 後回しにしても問題ないこともあれば、絶対に忘れてはいけない重要なこともあります。その代表格が「薬の服用時間」です。ほかにも、在宅勤務中のオンライン会議などは見逃せません。薬や通院予定の管理には、Systweakの「Medicine