←検索窓の楽しみ方
  ショッピングモール  掲示板ランキング


【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板1こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.4216

メモリ確保関数について
投稿者---gusha(2005/07/06 16:47:44)


realloc()関数についてお聞きします。

realloc()関数は、malloc()などで取得した領域のサイズを変更するときに使い、あらたに別アドレスの領域を変更になったサイズで取得する動きをします。

例:malloc()で、アドレス300から2バイトの領域を取得している。
  realloc()で、アドレス400から7バイトの領域へ変更する。

このときに、変更前に取得した領域(例のアドレス300から2バイト分)の解放は行われるのでしょうか?また、realloc()で同じアドレス(例のアドレス300)を取得することはありえますでしょうか?

お手数をおかけしますが、よろしくご回答をお願いいたします。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:メモリ確保関数について 4219 おでん 2005/07/06 17:00:45
<子記事> Re:メモリ確保関数について 4220 επιστημη 2005/07/06 17:03:56
<子記事> Re:メモリ確保関数について 4222 まきじ 2005/07/06 17:11:42
<子記事> Re:メモリ確保関数について 4224 円零 2005/07/06 17:19:14


No.4219

Re:メモリ確保関数について
投稿者---おでん(2005/07/06 17:00:45)


>realloc()関数は、malloc()などで取得した領域のサイズを変更するときに使い、あらたに別アドレスの領域を変更になったサイズで取得する動きをします。
>
本当にそんな動きをするのですか?


この投稿にコメントする

削除パスワード

No.4220

Re:メモリ確保関数について
投稿者---επιστημη(2005/07/06 17:03:56)


>このときに、変更前に取得した領域(例のアドレス300から2バイト分)の解放は行われるのでしょうか?また、realloc()で同じアドレス(例のアドレス300)を取得することはありえますでしょうか?

マニュアル/ドキュメントには書いてなかったのですか?



この投稿にコメントする

削除パスワード

No.4222

Re:メモリ確保関数について
投稿者---まきじ(2005/07/06 17:11:42)


>realloc()関数は、malloc()などで取得した領域のサイズを変更するときに使い、あらたに別アドレスの領域を変更になったサイズで取得する動きをします。
>このときに、変更前に取得した領域(例のアドレス300から2バイト分)の解放は行われるのでしょうか?また、realloc()で同じアドレス(例のアドレス300)を取得することはありえますでしょうか?

MSDN のには

引数 size には、変更後の新しいブロックのサイズをバイト単位で指定します。ブロックの内容は、新しいサイズと古いサイズのうち小さい方のサイズまでは同じですが、新しいブロックは別の位置に割り当てられる場合があります。再割り当てされた新しいブロックは、メモリ内の別の位置に割り当てられることがあるため、realloc 関数の戻り値が、引数 memblock で渡したポインタと異なる場合があります。

とあります。


この投稿にコメントする

削除パスワード

No.4224

Re:メモリ確保関数について
投稿者---円零(2005/07/06 17:19:14)


reallocで取得した領域は、元の領域と重なっている場合もあるし新しい領域である場合もあるようです。

新しい領域に確保した場合、元の領域は開放されます。
同じ領域のときはそのままですね。
なお、reallocが失敗したときは、元の領域は開放されません。
うっかり戻り値をノーチェックで代入してしまうとそのまんまになってしまうので要注意です。


この投稿にコメントする

削除パスワード

No.4226

Re:メモリ確保関数について
投稿者---gusha(2005/07/06 17:44:38)


迅速な回答ありがとうございます。
まず、お聞きしたいのですが、MSDNのものは、Visual C++ のライブラリからの情報のようですが、別のベンダーのCコンパイラ(たとえばsolarisやhpなど)のreallocも同じ動作をするということでよろしいでしょうか?

その上で、

・元の領域と重なる⇒ブロックの内容が、新しいサイズと古いサイズのうち小さい方のサイズのとき

・新しい領域をとる場合がある⇒古いサイズよりも大きくなるとき

ということでよろしいでしょうか?
realloc()で同じアドレスを取得するのは、どういうときなのか明確なケースがあるのでしょうか?

以上よろしくお願いいたします。

>reallocで取得した領域は、元の領域と重なっている場合もあるし新しい領域である場合もあるようです。
>
>新しい領域に確保した場合、元の領域は開放されます。
>同じ領域のときはそのままですね。
>なお、reallocが失敗したときは、元の領域は開放されません。
>うっかり戻り値をノーチェックで代入してしまうとそのまんまになってしまうので要注意です。



この投稿にコメントする

削除パスワード

No.4227

Re:メモリ確保関数について
投稿者---おでん(2005/07/06 17:59:43)


>
>・元の領域と重なる⇒ブロックの内容が、新しいサイズと古いサイズのうち小さい方のサイズのとき
>
>・新しい領域をとる場合がある⇒古いサイズよりも大きくなるとき
>
>ということでよろしいでしょうか?
>realloc()で同じアドレスを取得するのは、どういうときなのか明確なケースがあるのでしょうか?
>

全て「実装依存」です。

従って、realloc()が返してきたアドレスが拡張する前の領域アドレスと
同じである事は“保障されない”という認識でプログラムを作るべきです。

「引数 ptr が指す古いメモリブロックを解放し、 sizeバイトのメモリ
ブロックを割り付けます。」という処理系もあります。


この投稿にコメントする

削除パスワード

No.4228

Re:メモリ確保関数について
投稿者---円零(2005/07/06 18:10:24)


>・元の領域と重なる⇒ブロックの内容が、新しいサイズと古いサイズのうち小さい方のサイズのとき
それは内容(バイトの値)の一致の話じゃありませんか?
アドレスの話とごっちゃにされると話がしづらいんですが。

>・新しい領域をとる場合がある⇒古いサイズよりも大きくなるとき
>
>ということでよろしいでしょうか?
特にそう決められてはいません。
後ろが空いているならば、そのままメモリブロックを伸ばすことも理論的には可能ではないかと。

JISの該当する部分を引用しておきますね。

7.20.3.4 realloc関数
形式
    #include <stdlib.h>
    voud *realloc(void *ptr, size_t size);
機能 realloc関数は、ptrが指す古いオブジェクトを解放し、大きさがsizeである新しいオブジェク
トへのポインタを返す。新しいオブジェクトの内容は、新しいオブジェクトの大きさと古いオブジェクト
の大きさのうち小さい方の大きさまでの部分で、解放する前の古いオブジェクトの内容と同じでなければ
ならない。古いオブジェクトの大きさを超えた部分の新しいオブジェクトのバイトの値は、不定とする。
 ptrが空ポインタのとき、realloc関数は、指定された大きさでのmalloc関数と同じ動作をする。
それ以外の場合、ptrがcalloc関数、malloc関数若しくはrealloc関数によって以前に返されたポ
インタと一致しないとき、又は領域がfree関数若しくはrealloc関数の呼出しによって解放されてい
るとき、その動作は、未定義とする。新しいオブジェクトに対する記憶域の割付けができなかった場合、
古いオブジェクトは解放されずその値は変化しない。
返却値 realloc関数は、新しいオブジェクトへのポインタを返す(古いオブジェクトへのポインタと同
じ値かもしれない。)。新しいオブジェクトの割付けができなかった場合、空ポインタを返す。


この投稿にコメントする

削除パスワード

No.4229

Re:メモリ確保関数について
投稿者---gusha(2005/07/06 18:30:20)


迅速な回答ありがとうございました。

実装依存であり、reallocの戻り値である、再確保されたメモリブロックへのポインタ は、すでにメモリ確保されたブロックへのポインタとは、一致するときもあれば別のときもあり、明確な動作の差異を規定するようなコーディングはできないということですね?

了解しました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity