指している領域が移動した場合、free(ptr)が実行されます。
上記の行について説明していただけますrealloc()
か?この行は、calloc、malloc、realloc、およびfreeのmanページからのものです。
私はこれがそれをよりよく説明すると思います:
現在のブロックを現在の場所に拡張するのに十分なスペースが存在しない場合、サイズに応じたサイズの新しいブロックが割り当てられ、既存のデータが古いブロックから新しいブロックの先頭にコピーされます。古いブロックが解放され、関数は新しいブロックへのポインターを返します。
Cのreallocから取得した参照
次のヒープレイアウトがあるとします。これは、制御情報によってヒープ内のスペースが占有されない単純化されたメモリアロケータです。
Addr A B
+------------+ +------------+
1000 | your space | | your space |
+------------+ +------------+
2000 | free space | | used space |
| | +------------+
3000 | | | free space |
| | | |
4000 | | | |
+------------+ +------------+
どちらの状況でも、アドレス1000に1000バイトが割り当てられています。ただし、状況Bでは、この直後に他の目的で割り当てられたメモリが続きます。
メモリを2000バイトに再割り当てしたいときに何が起こるかを調べてみましょう。
状況Aでは、これは簡単です。次の図のように、割り当てを拡張するだけです。
しかし、状況Bでは、それはそれほど簡単ではありません。ブロックの直後のメモリが使用されているため、割り当てを拡張するだけの十分なスペースがなく、連続したメモリが必要です。2つの状況の終了位置は次のとおりです。
Addr A B
+------------+ +------------+
1000 | your space | | free space |
| | +------------+
2000 | | | used space |
+------------+ +------------+
3000 | free space | | your space |
| | | |
4000 | | | |
+------------+ +------------+
状況Bの場合、アロケータは目的の拡張に十分な大きさのブロック(3000)を見つけ、現在のブロック(1000)の内容をそれにコピーします。次に、この新しいブロックのアドレスを提供し、古いブロックを解放します。これは、それが不要になったためです。それがあなたの質問のフレーズの意味です。
バッファを移動するこのアクションは、メモリ割り当て戦略によって異なりますが、通常、次のいずれかの場合、バッファは移動されません(大量のメモリコピーが含まれるため、多くの場合、コストがかかります)。
常にその場でメモリ領域を拡大できるとは限りません。ヒープにスペースがない可能性があります。したがって、拡張する代わりに、完全に新しいメモリブロックを割り当て、古いメモリを解放します。