リンカ・ローダと実行形式

C言語の「char *p = "hello"; p[0] = 'H';」を実行すると、多くの環境で異常終了する。その理由として正しいものはどれか。

  1. A文字列はスタックに置かれ、関数から戻ったため消えていたから
  2. B文字列リテラルは書き込み禁止の.rodataに置かれ、そこに書き込もうとしたから
  3. Cpが0で初期化されていたから
答えと解説を見る

正解:B. 文字列リテラルは書き込み禁止の.rodataに置かれ、そこに書き込もうとしたから

"hello"のような文字列リテラルや、constを付けたグローバル定数は、読み取り専用のデータ領域(.rodata)に置かれます。このページは書き込みが禁止されているので、書き込もうとするとCPUが保護違反を検出し、OSがプログラムを止めます(セグメンテーション違反)。書き換えたい場合は「char s[] = "hello";」と配列にすれば、書き込める領域にコピーが作られます。

  • A. 文字列リテラルはプログラムの実行中ずっと残ります。
  • B. 正しい。書き込みで保護違反になります。
  • C. pは文字列の先頭を指しています。
この分野を解く 分野ページへ

リンカ・ローダと実行形式のほかの問題

  1. 上のグローバル変数のうち、一般に.bssセクションに置かれるものの組み合わせはどれか。
  2. C言語の関数の中で宣言した、staticの付かない局所変数(自動変数)は、実行中どこに置かれるか。
  3. C言語のmallocで確保したメモリは、一般にプロセスのどの領域から取られるか。
  4. Linuxなどの一般的なプロセスのメモリ配置を、番地の小さい方から並べたものとして正しいものはどれか。
  5. プロセスのヒープとスタックを、間に広い空きをはさんで反対向きに伸ばす配置にする利点として正しいものはどれか。