C言語のメモリ割り当てとコンパイルプロセスに関する選択問題(MCQ)5問を徹底解説
この記事では、C言語におけるメモリ割り当てとコンパイルプロセスに関する選択式問題(MCQ)を5問取り上げ、それぞれの正解と詳しい解説を紹介します。C言語の基礎固めや試験対策にぜひ活用してください。
問題1:共用体(union)を使ったコードの出力結果は?
次のコードを実行すると、どのような出力になるでしょうか。
#include <stdio.h>
#include <stdlib.h>
int main() {
union my_union {
int i;
float f;
char c;
};
union my_union* u;
u = (union my_union*)malloc(sizeof(union my_union));
u->f = 20.60f;
printf("%f", u->f);
}
選択肢:
- A. ガベージ値(不定値)
- B. 20.600000
- C. 構文エラー
- D. 20.6
解説
正解:B(20.600000)
共用体(union)では、複数の異なる型のデータを同一のメモリ領域で共有できます。すべてのメンバーは、最もサイズの大きいメンバーと同じメモリ位置を使用します。このコードではfloat型に20.60fを代入しているため、%f指定子で出力されると小数点以下6桁の「20.600000」と表示されます。
問題2:コンパイルプロセスの正しい順序は?
C言語のソースコードが実行可能ファイルになるまでの処理順序として正しいものを選んでください。
選択肢:
- A. アセンブラ → コンパイラ → プリプロセッサ → リンカ
- B. コンパイラ → アセンブラ → プリプロセッサ → リンカ
- C. プリプロセッサ → コンパイラ → アセンブラ → リンカ
- D. アセンブラ → コンパイラ → リンカ → プリプロセッサ
解説
正解:C(プリプロセッサ → コンパイラ → アセンブラ → リンカ)
C言語のビルドプロセスは、まずプリプロセッサが#includeや#defineなどの前処理指令を展開し、次にコンパイラがソースコードをアセンブリコードに変換します。その後アセンブラがオブジェクトコード(.oファイルなど)を生成し、最後にリンカがライブラリや他のオブジェクトファイルと結合して実行可能ファイルを作成します。
問題3:#include文がstdio.hの内容に置き換えられるのはどの段階?
選択肢:
- A. リンク時
- B. プリプロセス時
- C. 実行時
- D. 編集時
解説
正解:B(プリプロセス時)
#include文は、プリプロセッサによって処理されます。プリプロセッサは、#includeで指定されたヘッダファイル(stdio.hなど)の内容をその位置に展開・挿入し、前処理済みのコードとしてコンパイラに渡します。リンク時や実行時には既にヘッダの内容は組み込まれています。
問題4:fflush()関数の目的は?
選択肢:
- A. すべてのストリームおよび指定されたストリームをフラッシュする
- B. 指定されたストリームのみをフラッシュする
- C. 入出力バッファをフラッシュする
- D. 無効なライブラリ関数である
解説
正解:A
fflush()関数は、出力ストリームをフラッシュするために使用されます。出力バッファに残っているデータを強制的に書き出し、コンソールなどに出力します。引数にNULLを渡すと、すべての出力ストリームがフラッシュされるため、選択肢Aが正解です。なお、標準C規格では入力ストリームに対するfflush()の動作は未定義となっている点にも注意しましょう。
問題5:次のコードの誤りはどこ?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char* ptr;
*ptr = (int*)malloc(30);
strcpy(ptr, "ABC");
printf("%s", ptr);
free(ptr);
}
選択肢:
- A. strcpy()文に誤りがある
- B. *ptr = (int*)malloc(30); に誤りがある
- C. free(ptr)に誤りがある
- D. 誤りはない
解説
正解:B(*ptr = (int*)malloc(30);)
このコードには2つの重大な問題があります。まず、*ptr = (int*)malloc(30);では、ポインタptr自体ではなく、ptrが指す先(未初期化の不正なアドレス)にmallocの戻り値を代入してしまっています。これにより「pointerからintegerへの代入」に関する警告や未定義動作が発生します。また、キャストもchar*ではなくint*になっており不適切です。
正しくは次のように書くべきです。
char* ptr = (char*)malloc(30);
さらに、malloc()の戻り値がNULLでないかを必ずチェックすることも重要です。NULLチェックを怠ると、メモリ確保に失敗した場合にstrcpy()がクラッシュを引き起こす可能性があります。
まとめ
今回の5問を通じて、共用体のメモリ共有の仕組み、コンパイルの各段階(プリプロセス→コンパイル→アセンブル→リンク)、#includeの処理タイミング、fflush()の役割、そしてmalloc()とポインタの正しい扱い方について学べました。これらはC言語の試験や面接で頻出のトピックなので、しっかり理解しておきましょう。
-
【解決法】wsappxによるCPU・メモリ使用率の高騰を直す4つの方法
Wsappxは、タスクマネージャーのプロセス一覧に表示されるプロセスの一つです。「そもそもこれは何?」、「なぜこんなにCPUを使うのか?」と疑問に思った方も多いのではないでしょうか。wsappxのCPU使用率は増えたり減ったりと変動します。ほとんどリソースを使っていないときもあれば、急に高い使用率を示すこともあります。このプロセスをダブルクリックすると、wsappxの下にさらに2つのサブプロセスが表示され、それぞれ「AppXSVC」と「ClipSVC」(Windows 8では「WSService」)という名前になっています。また、タスクマネージャー上に複数のwsappxインスタンスが並んで表示
-
Windows 10で「システムと圧縮メモリ」によるディスク使用率100%問題を解決する6つの方法
Windows 10に搭載されている「システムと圧縮メモリ(System and Compressed Memory)」は、RAM上でファイルやフォルダの割り当てを行うプロセスです。通常、このプロセスはシステムやメモリに関する処理をわずかなリソースで実行します。しかし、本来は空き容量を作るはずのプロセスが、逆にディスク使用率を100%まで押し上げてしまう問題が発生することがあります。このプロセスが高負荷状態になると、他のプログラムの動作にも悪影響が及びます。実際に多くのユーザーから、「Windows 10のシステムと圧縮メモリが必要以上にディスクを使用している」という報告が寄せられています。