[2207] Re:c言語ポインタ完全制覇(改訂版)に関する質問
投稿者:(ぱ)こと管理人
2019/12/29 14:42:22
はじめまして。
>realloc関数について man command で調べたところ(準拠 C89 C99)、返り値の項で
>>「realloc関数は新たに割り当てられたメモリーへのポインタを返す。これはあらゆる
>>組み込み型に対応できるようにアラインメントされており、ptrとは異なることも
>ある。」と説明されています。
はい。realloc()は引数で渡されたポインタとは異なるポインタを返すこともあります。
2-6-6(p.147)にも書いたとおりです。
>List 4-4 realloc.cの17~19行目のfor文のブロックでsscanf関数によって
>ヒープ領域にストアした値をprintf関数により、variable_array[i]という形で
>参照しています。これは実際には *(variable_array + i) という形に
>読み替えられていると思います。 ただ、上記のmanコマンドの返り値の項で
>記述されている「ptrとは異なることもある」が実際に起こった場合、
>List 4-4 におけるptrつまりvariable_arrayが指し示すメモリアドレスが
>一定ではなくなると思うので、そのメモリアドレスを起点にしてアクセスする
>*(variable_array + i)は上手く目的の値をとってくることが、
>できないのではないでしょうか。
どこに疑問を持たれているのかいまひとつわかりませんが、
確かにrealloc()は異なるアドレスを返すことがあります。
たとえばrealloc()が6回目までは同じアドレスAを返し、7回目の呼び出しで
アドレスBを返したとして、Bを返すとき、realloc()は
A[0]~A[5]をB[0]~B[5]にコピーしてから返します。
よって、このサンプルでは、17行目からのforループで値を表示することは
問題なくできます。
これで回答になっていますでしょうか?
>今まだ4章の途中ですが、本当にたくさんのことも学ぶことができています。
>自身の環境で実験をしながら試行錯誤ができ、とてもおもしろいです。
>本を書いてくださりありがとうございました。
ありがとうございます。
実験できる環境があるのでしたら、realloc()の下で実際にポインタの値を
表示してみると挙動がわかるかもしれません。
具体的には13行目と14行目の間に以下の2行を挿入します。
printf("variable_array..%p\n", variable_array);
malloc(10);
明らかに無駄に見える2行目のmalloc(10);は、realloc()で確保した領域の
続きを埋めることでrealloc()が別の領域を返すことを促すためのものです
(コンパイラが最適化で消してしまうかもしれませんが、私の環境(Linux上のgcc)では
最適化オプションを付けなければ大丈夫でした)。これを付けないと、
何度呼んでもrealloc()は同じアドレスを返しました。後ろが空いているからでしょう
(p.147参照)。
上記2行を足すことで、私の環境では、realloc()は7回目で異なるアドレスを
返してきました。