K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]


新規投稿 | 開設者ホームページへ戻る | ヘルプ


[2206] c言語ポインタ完全制覇(改訂版)に関する質問
返信


投稿者:Hello World
2019/12/27 19:06:55

Link:
・realloc関数についての質問(p238 List 4-4 realloc.c)
 realloc関数の呼び出しは13行目
  
   variable_array = realloc(variable_array, sizeof(int) * size);

realloc関数について man command で調べたところ(準拠 C89 C99)、返り値の項で
「realloc関数は新たに割り当てられたメモリーへのポインタを返す。これはあらゆる組み込み型に対応できるようにアラインメントされており、ptrとは異なることもある。」と説明されています。

man command のrealloc関数の書式は以下の通り。
   void *realloc(void *ptr, size_t size);

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)は上手く目的の値をとってくることが、できないのではないでしょうか。

拙い文ではありますが、何卒よろしくお願いします。

今まだ4章の途中ですが、本当にたくさんのことも学ぶことができています。
自身の環境で実験をしながら試行錯誤ができ、とてもおもしろいです。
本を書いてくださりありがとうございました。
[ この投稿を含むスレッドを表示] [ この投稿を削除]



[2207] Re:c言語ポインタ完全制覇(改訂版)に関する質問
返信


投稿者:(ぱ)こと管理人
2019/12/29 14:42:22

Link:
はじめまして。

>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回目で異なるアドレスを
返してきました。
[ この投稿を含むスレッドを表示] [ この投稿を削除]



[2208] Re:c言語ポインタ完全制覇(改訂版)に関する質問
返信


投稿者:Hello World
2020/01/02 15:39:55

Link:
回答ありがとうございます。と共に返信遅くなり、申し訳ありません。

>はい。realloc()は引数で渡されたポインタとは異なるポインタを返すこともあります。
>2-6-6(p.147)にも書いたとおりです。

2-6-6 読み直しました。4章(List 4-4 realloc.c)で色々試したことにより深く理解することができました。 ありがとうございます。

>どこに疑問を持たれているのかいまひとつわかりませんが、
>確かにrealloc()は異なるアドレスを返すことがあります。
>たとえばrealloc()が6回目までは同じアドレスAを返し、7回目の呼び出しで
>アドレスBを返したとして、Bを返すとき、realloc()は
>A[0]〜A[5]をB[0]〜B[5]にコピーしてから返します。
>よって、このサンプルでは、17行目からのforループで値を表示することは
>問題なくできます。
>
>これで回答になっていますでしょうか?

はい、的確な回答ありがとうございます。
17行目の部分も理解することができました。ありがとうございます。


>実験できる環境があるのでしたら、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回目で異なるアドレスを
>返してきました。

アドレスを表示することは何度もやっていましたが、mallocにより別の領域を返すことを促す発想はありませんでした。
ちなみにわたしの環境では、realloc()は6回目で異なるアドレスを返してきました。

もう一つ質問があります。
ポインタ完全制覇を読んでみて、処理系がどのようにプログラマーの書いたコードを解釈しているのかが理解できれば、より理解が深まるなと考えています。そこで処理系に関する
おすすめの書籍などがあれば教えていただけると非常に嬉しいです。

回答ありがとうございました。
[ この投稿を含むスレッドを表示] [ この投稿を削除]



[2209] Re:c言語ポインタ完全制覇(改訂版)に関する質問
返信


投稿者:(ぱ)こと管理人
2020/01/03 21:13:33

Link:
>もう一つ質問があります。
>ポインタ完全制覇を読んでみて、処理系がどのようにプログラマーの書いたコードを
>解釈しているのかが理解できれば、より理解が深まるなと考えています。
>そこで処理系に関するおすすめの書籍などがあれば教えていただけると非常に嬉しいです。

処理系に関する本、というと私が答えるなら当然これになるわけですが

プログラミング言語を作る
https://amzn.to/2szojNN

10年前の本なので新刊入手は難しいでしょうし、「機械語を生成するCコンパイラ」を
作っているわけではないのでHello Worldさんの目的にはちょっと合わないかもしれません。

Web版なら無料なのでよろしければどうぞ。crowbarはともかくDiksamの方は、
バイトコードコンパイル型の言語なのでCにも通じるところはあるかと思います。

http://kmaebashi.com/programmer/devlang/index.html

機械語を生成するCコンパイラの本であれば、私が大昔に読んだのはこれですが、

yaccによるCコンパイラプログラミング 
https://amzn.to/2SP8bT1

こちらも入手困難かもしれません(昔はマーケットプレイスでとんでもない高値が
ついていました……)。

今なら、Rui Ueyamaさんの、こちらのページとかどうでしょうか(完結していませんが)。

https://www.sigbus.info/compilerbook

[ この投稿を含むスレッドを表示] [ この投稿を削除]



[2210] Re:c言語ポインタ完全制覇(改訂版)に関する質問
返信


投稿者:Hello World
2020/01/05 12:09:19

Link:
回答ありがとうございます。
すぐに読ませていただきます。
[ この投稿を含むスレッドを表示] [ この投稿を削除]