C/C++のポインタの機能--参照渡しのような処理(ZDNet) †マトモそうなサイトの中では,おそらく史上最凶のポインタの解説記事. どう最凶かは,次のサンプルプログラムを見れば一目瞭然. #include <stdio.h> int main( void ) { int *n; *n = 5; /* ポインタ変数nに値5を代入 */ printf( "%d\n", *n ); /* ポインタ変数nが持つ値(5)の出力 */ return 0; } 初期化していないポインタの指し示すアドレスに 5 を書き込んでいる. もちろんこんなものマトモに動くはずもなく,x86 Linux では Segmentation fault で止まる. gdb でのトレース †こんなのをくどくど説明するのもアホらしいのだけど,gdb でトレースすると以下のようになる. (gdb) b main Breakpoint 1 at 0x8048385: file hoge.c, line 6. (gdb) c The program is not being run. (gdb) run Starting program: /home/imai/a.out Breakpoint 1, main () at hoge.c:6 6 *n = 5; /* ポインタ変数nに値5を代入 */ (gdb) print n $1 = (int *) 0x4730b0b0 (gdb) n Program received signal SIGSEGV, Segmentation fault. 0x08048388 in main () at hoge.c:6 6 *n = 5; /* ポインタ変数nに値5を代入 */ (gdb) c Continuing. Program terminated with signal SIGSEGV, Segmentation fault. The program no longer exists. つまり, int *n; の時点では,n の値は不定なので,これを絵に描くと +--------+ n |??? O----------> unknown memory +--------+ となる. *n = 5; で
という操作を行うのだが,このアドレスは当該プロセスには割り当てられていない. このため例外が発生し,めでたく Segmentation fault で異常終了するわけである. うまく動いてしまう場合 †で,このプログラム,環境や運によってはうまく動いてしまうことも有り得る. (gdb) b main Breakpoint 1 at 0x8048385: file hoge.c, line 6. (gdb) run Starting program: /home/imai/a.out Breakpoint 1, main () at hoge.c:6 6 *n = 5; /* ポインタ変数nに値5を代入 */ (gdb) print &n $1 = (int **) 0xbfd54780 (gdb) set n=0xbfd50000 (gdb) c Continuing. 5 Program exited normally. (gdb) q ここではデバッガ上で (gdb) set n=0xbfd50000 で n の初期値を手動で設定して,「運がいい場合」をシミュレートしている. このアドレスはスタック領域近辺であり,プロセスにはメモリが割り当てられている. n の初期値がこんな値の場合はプログラムは無事実行され,正常終了する. どんな場合でも動作するようにするには †元記事のコメントや戯れメモのほうにも上がっているのだが,要するに
すればよいだけの話である. そうすれば運や環境に左右されず,汎用的に正常動作するプログラムとなる. というわけでこの記事は †この記事が公開されてしまったいきさつを最大限に良い方に解釈すると
というシナリオが考えられる. が,イカレたサンプルプログラムを元に説明しているので,説明自体もイカレている.
「自動的に代入されるアドレス」って何だろう? 「int *n で int 型変数の格納領域が確保される」という意味なのか,*n = 5 の時点で 「5 という整数型オブジェクトの格納アドレスが n に代入される」という意味なのか. 意味不明である. で,元記事コメントを見ている限りでは,編集部は
という認識のようであるが,実際のところ
なわけで. 考えてみれば †編集部内にこのような記事が書ける人がいれば,外部のライタには頼まずに編集部名義で記事を書くはずである. というわけでライタに記事を書いてもらったのだけど,それが正しいかどうかチェックする仕組みが無く「そのライタを信用する」しか無いのではないか. で,そのライタが怪しい場合は… そういう体制なんじゃないか,と,想像してみたりもする. |