reallocの存在意義

このエントリーをはてなブックマークに追加
1名無しさん@お腹いっぱい。
malloc@` calloc@` realloc@` freeの4つのメモリ関連の標準関数のうち
reallocだけ存在意義がわかりません。

mallocとfreeだけでもほとんどことたります。

callocもあってもいいかなとは思います。
(配列は一般にサイズが大きくなるから別管理したほうが効率が可能性もあるし)

reallocは移動することもあるししないこともある、というのが使いにくくてしょうがないです。
いったい、reallocが存在するとどんなメリットがあるのでしょう?
2名無しさん@お腹いっぱい。 :2000/09/27(水) 22:54
free して、別の大きさで malloc するときだよ。
3名無しさん@お腹いっぱい。 :2000/09/27(水) 22:59
>2
freeして、mallocするのに比べて効率がいいんですか?
freeしてサイズを変えてmallocするなんて、効率が悪いから普通はしないと思うのですが。
4( ´∀`)さん :2000/09/27(水) 23:04
>freeしてサイズを変えてmallocするなんて、効率が悪いから普通はしないと思うのですが。
だからreallocがあるんだろうが。
5名無しさん@お腹いっぱい。 :2000/09/27(水) 23:05
reallocのどのへんが効率がいいんでしょうか?
6名無しさん@お腹いっぱい。 :2000/09/27(水) 23:06
普通はそういう場合はリストを使うと思うんですが。
reallocが効率よく機能する場面てあるんですか?
7名無しさん@お腹いっぱい。 :2000/09/27(水) 23:07
*現在のデータを維持しつつ*サイズを大きく、小さく出来るのが
便利なので必要だと思います。

malloc、freeだと
*新たなサイズのメモリをmallocする。
*前のデータを新しいメモリにコピーする
*前のデータをfree
ということになって面倒だと思います。
8名無しさん@お腹いっぱい。 :2000/09/27(水) 23:10
>>6
>普通はそういう場合はリストを使うと思うんですが。
 おまえ、一度リスト作ってみろよ。
91 :2000/09/27(水) 23:15
サイズを小さくしたいことってあるんですか?
多少、大きくても普通は問題ない気がするんですが。

コピーを伴うような、再確保を頻繁に行うのはいい設計とはいえないですし...。
10名無しさん@お腹いっぱい。 :2000/09/27(水) 23:20
reallocと同等の処理を、mallocとfreeの組み合わせで書いてみて、
ベンチマークしてみなよ。
たいていの環境でreallocのほうが速いから。
111 :2000/09/27(水) 23:22
>8
普段は逐次的な読み込みなんかは、とりあえず、双方向リングかニ分木を使ってます。
アクセス性能が問題になって、個数の変化の少ないデータは、全体の数が確定した時点で、
大きな配列を確保して、そちらにコピーしてますが?なにか?
12名無しさん@お腹いっぱい。 :2000/09/27(水) 23:24
>9
いちいちリスト使ってたらアクセス遅くていらいらしない?
    &
リストは何度もmalloc呼ぶ羽目になるから重くなりがち、
使い所を考えないと自己満足で終わる。あんたは多分そういうタイプ。
13名無しさん@お腹いっぱい。 :2000/09/27(水) 23:24
メモリをケチるのに使う。
141 :2000/09/27(水) 23:25
>10
freeしてmallocしなければならない場面が、そんなにないと思うんですが?
具体的にどんな処理をするときに有効ですか?
15名無しさん@お腹いっぱい。 :2000/09/27(水) 23:26
>1
おまえ、煽り下手。
ネタのつもりだろうが、スレッドの最初っから、プンプン臭って
くるし、見ているこっちが恥ずかしくなるよ。
修行が足りんよ、出直しておいで。
16宇津田志野 :2000/09/27(水) 23:27
何であげてんだ……
171 :2000/09/27(水) 23:29
うーん。何度もmalloc呼ぶリストの実装はおバカですね。
普通はおおよそのまとまった個数のリスト要素の配列を確保するんじゃないんですか?
あと、逐次的な処理しているときは、リストで十分です。

ランダムアクセスしながら、逐次的にデータが増えるってそうそうない場面だと思います。
181 :2000/09/27(水) 23:30
あおってるつもりないんですが...。
本気で、reallocが何で必要なのかわかんないです。
reallocを多用することそのものが、設計の間違いだと思います。
19名無しさん@お腹いっぱい。 :2000/09/27(水) 23:33
>1
だれが多用してるの?
20名無しさん@お腹いっぱい。 :2000/09/27(水) 23:35
>freeしてサイズを変えてmallocするなんて、効率が悪いから普通はし
>ないと思うのですが。
 だからreallocがあるんだろうが。(4さんのこぴぺ)

>サイズを小さくしたいことってあるんですか?
 あったらどうするんだよ

>個数の変化の少ないデータは、全体の数が確定した時点で、
 個数変化の多い、全体の数を確定できないデータの場合は?

>ランダムアクセスしながら、逐次的にデータが増えるってそうそうな
>い場面だと思います。
 だから、あったらどうするんだよ。

 以上、答えは全て自分で答えております。

よってこのスレッド、終了。

211 :2000/09/27(水) 23:36
reallocの特徴は次の領域が運良くあいていたら、解放しないで
拡張できるところですよね。
問題は、大抵のプログラムでは、拡張する前に立て続けにmallocが呼ばれることが多いから、
結局拡張できない可能性があるわけで...。

どうしても、しょっちゅう拡張しなくちゃいけないようなものは、
最初から、多めに割り当てるか、16個とか32個ぐらいのブロックごとに
リンクでつなぐという選択肢が妥当だと思います。
22名無しさん@お腹いっぱい。 :2000/09/27(水) 23:36
>1
本気でreallocいらないの?
vectorみたいな可変長配列欲しいと思ったことない?
23名無しさん@お腹いっぱい。 :2000/09/27(水) 23:37
>14
可変長のデータを処理する時。
つーかそういうレベルで文句言うなら、callocだっていらないし、
ムダな関数は他にもたくさんある。
24名無しさん@お腹いっぱい。 :2000/09/27(水) 23:40
配列などのデータ構造で、可変長にしたいとき、再割り当てにmalloc(新しいサイズ)->free(古いサイズ)の順に呼出すと、必ずメモリの断片化が起こります。その問題をランタイムライブラリ側でなるべく吸収させるという事が1つ。
また、現在確保されている領域の隣りにちょうど空きがあった場合、単に領域サイズを広げるのみで、内部でmalloc/freeに相当する処理を呼ぶ事が無いので、多少効率が良いかもしれません。
ただし、reallocは失敗時の振る舞いが処理系毎に異なっていて、問題が起った経験があるので、わたし自身、あまり使用していません。

あとは、malloc/free/realloc自体は遅い処理なので、効率を考えるならば、最初にメモリブロックを大きく取るなどの、他の方法を考えた方が良いです。
251 :2000/09/27(水) 23:42
こういうアプリケーションで、reallocは有効だ!
という具体的な例をだしてほしいです。

あったらどうするか?で、
ライブラリは作られているわけではないですよね?

標準に選ばれたからには、なんらかの存在意義と、アプリケーションが想定されていたはずだと思うんです。

ランダムアクセスしながら、逐次的にデータが増えるというのは、
具体的にどんなアプリケーションが考えられますか?
26名無しさん@お腹いっぱい。 :2000/09/27(水) 23:42
うん、要らない。realloc要らない。
もう、要らないでいいから、お前だけ一生realloc使うな。
じゃあね。
27名無しさん@お腹いっぱい。 :2000/09/27(水) 23:46
このスレ、得るものないから、もう終わりでいい気がする・・・。そろそろ沈めよ。

>1
そういうわけだからこれからはsageで書け。
28名無しさん@お腹いっぱい。 :2000/09/27(水) 23:47
1は一生静的配列だけを使うこと。
29名無しさん@お腹いっぱい。 :2000/09/27(水) 23:48
>1
「reallocを多用するのは設計の間違い」って前提が間違ってる。
世の中そんなガリガリに最適化が必要なアプリばかりじゃない。
30名無しさん@お腹いっぱい。 :2000/09/27(水) 23:49
>28
むしろ、
int val1@` val2@` val3@` val4...;
みたいな(藁
31名無しさん@お腹いっぱい。 :2000/09/27(水) 23:51
24ですが、
reallocが在った方が良いか、無い方が良いか、という議論ならば、別に無くても良いですね。(笑)

25 > 文字列型を自分で作る場合とかで可変長配列は必要だと思いますけど。reallocしなければいけないわけじゃないけどね。

32名無しさん@お腹いっぱい。 :2000/09/27(水) 23:54
1は自分の了見の狭さを恥じるべし
33名無しさん@お腹いっぱい。 :2000/09/27(水) 23:57
1は最近リンクリストの使い方を覚えた厨房。
341 :2000/09/28(木) 00:00
>24
どうもありがとうございます。
malloc -> freeだと"必ず"断片化が起こるという、ご指摘はなるほどと思いました。
たしかに大きな存在意義ですね。

>29
動けばいいなら、最初からメモリを多めに確保しておいて、たまに
malloc/freeしてもそんなに問題ないわけで、
ライブラリに用意されているということは多用する処理だからこそ、
なんだと思いますが?
35名無しさん@お腹いっぱい。 :2000/09/28(木) 00:01
reallocなんて、なくても困らないけど、あったからどうって事もない。
議論自体が無意味な気がする・・・。
ところで1はどうした?
3635 :2000/09/28(木) 00:02
もどってきたのね。
371 :2000/09/28(木) 00:05
データの個数の上限が決まっていて、かつ個数が非常に少ないことも
多いこともあるデータを、プログラム起動時にファイルから読み込む場合なんかは、
上限一杯で、mallocしておいて、ファイルの読み込みが終わったらreallocして
切り詰めるって使い方は意味がありそうですね。
381 :2000/09/28(木) 00:25
reallocって、なんかのライブラリ関数が多用してるのかなぁ..。
39名無しさん@お腹いっぱい。 :2000/09/28(木) 00:33
24です。
処理系がVisualC++やgccならランタイムのソースも見れると思いますよ。こーゆーのは自分で確認するのが一番だと思います。
reallocはメモリがシビアな環境(16bitのMSDOSとか)でもない限り、現在ではあまり意味は無いと思います。

40名無しさん@お腹いっぱい。 :2000/09/28(木) 00:40
どうでもいいが1は質問のしかたを知らないね。
最初から、なぜreallocが必要無いか書いとけよ。
つっこみがあってから反論してないでよ。
411 :2000/09/28(木) 00:48
>24
お付き合いありがとうございます。
#こんなレスしかつかないなら、最初からソースみればよかったとおもいました。

実際のところ、あまり意味がないのかな。
C++のフリーストアにreallocに等価なものが定義されていないというのもその現れなのかなぁ。
421 :2000/09/28(木) 00:54
>40
別に、必要無いという主張をしたくて、スレッドを立てたわけじゃなくて、
自分で考える限りほとんど必要性を感じないのに、なんでライブラリにあるのかなぁと。

標準ライブラリ関数に選ばれるからには、選ばれたときはなにかの理由があったはずです。
43名無しさん@お腹いっぱい。 :2000/09/28(木) 01:03
>42
こいつ天然ですか?
44名無しさん@お腹いっぱい。 :2000/09/28(木) 01:14
勝手に論破されたと思った厨房が一生懸命もがいてるよ。
ホントに、夏休み以来どうしようも無いほどにレベルがさがったもんだ。

1もダメだよ。こんな板でマジメに聞いたら。
サル以下しかいないんだから。ケケケ。
45>43 :2000/09/28(木) 01:14
天然じゃなくて釣りの好きな人でしょ。
46名無しさん@お腹いっぱい。 :2000/09/28(木) 02:22
>44
どう見てももがいてるのはチミだと思う。
47名無しさん@お腹いっぱい。 :2000/09/28(木) 05:26
C++はコンストラクタとかがあるおかげでreallocが無いのは基本の話ですね。
48名無しさん@お腹いっぱい。 :2000/09/28(木) 08:46
>>47
「基本の話」だというのに、非常に恐縮だが、
なんで??
49++ :2000/09/28(木) 09:45
realloc()は便利だと思うよ
領域の拡張なんかする時
malloc() とfree()でやると
100の領域に10追加したいとき

・100+10 をまず確保して、
・元の100のデータをそこに移して
・元の100を解放する

って一連の操作がrealloc()
1つでできるからね

(例なんで、異常系の処理が抜けてるとかいわんでね・・)

50>48 :2000/09/28(木) 10:51
C++には再配置コンストラクタが無いからだ。
51名無しさん@お腹いっぱい。 :2000/09/28(木) 11:12
reallocはサイズが前と同じなら必ず同じ場所を返すのかな?
というかそれを皆、期待してるのかな?

浮いていたら詰めるような動作をさせれば、メモリフラグメントの解決に
使えるんじゃないかと。
52名無しさん@お腹いっぱい。 :2000/09/28(木) 11:28
昔、シリアルから読み出したメッセージを格納する時に、
バッファを切り詰めるのにreallocを使ったな。このときばかりは、reallocはありがたかった。
とりあえず最大メッセージ長でmallocしておいて、区切り文字がくるたびに、
reallocして切り詰めて返す。って処理ね。

しかし、今考えてみると、reallocって、切り詰めた場合、必ず同じ場所を返すことが保証されてる
のだろうか?
最近のメモリ豊富な状況を考えると、reallocってほとんど使い道ないね。
53名無しさん@お腹いっぱい。 :2000/09/28(木) 11:36
ログ等を文字列バッファに追加(連結)する関数。
realloc無しだと下のようになると思うけど...
めちゃくちゃ効率悪いね。
int foo(const char *str_to_add)
{
 static char *psz = NULL;
char *psznew;
 psznew = malloc(...);
 if(psznew == NULL) return 0;
 memcpy(...);
 memcpy(...);
 free(psz);
 psz = psznew;
 return 1;
}
54>52 :2000/09/28(木) 11:49
いくら豊富でも、オブジェクト指向言語みたいに非同期に
頻繁にalloc/freeするシステムでは、やがて フラグメンテーション
の為にメモリの利用効率が悪くなってゆく。
これが制御系でCが未だに主に使われ、C++が普及しない理由のひとつ

オブジェクトのメモリ割り当てをもう少し細かく制御出来る仕掛けが
必要なように思う
55名無しさん@お腹いっぱい。 :2000/09/28(木) 11:53
if(size < numElements){
size += XXX;
oldElemens = elements;
elements = (FOO **)realloc(elements@` sizeof(FOO *) * size);
if(elements == NULL){
XXXX;
}
}
elements[numElements ++] = newFoo;
56名無しさん@お腹いっぱい。 :2000/09/28(木) 14:53
>55
何がいいたいのか解説しろよ。
57名無しさん@お腹いっぱい。 :2000/09/28(木) 17:45
>>55
何が言いたいのか判らないが、oldElemens が何処かに逝っちゃってる
58名無しさん@お腹いっぱい。 :2000/09/28(木) 20:21
>57
>XXXX;
で使うんじゃない?
elementsの値を戻すとか。

でも、こんなコード書くより日本語で一言
「配列の拡大」って書いた方が早くない?
59。> :2000/09/28(木) 22:28
うーん、俺も、reallocってほとんど使わないから、確認はしてないけど、
仮想空間上で領域を再確保するなら、ページマッピングが変わるだけで、
領域コピーは発生しないから、効率よく拡張できるはずだけど。
そうなってないのか?
malloc+freeで擬似的に実現するのとは、違う動作を期待するが。
601 :2000/09/28(木) 23:12
MSのcrtだと、malloc/realloc/freeはそれぞれ
HeapAlloc/HeapReAlloc/HeapFreeを呼んでるみたいです。

Heep系のAPIはページ単位で確保するわけでない(ですよね?)ので、
ページマッピングの移動だけというわけにはいかなそうな気がします。

GNUのライブラリはもうちょっと賢い実装してあるのかな。
今、手元にソースがないので今度みてみます。
61。>60 :2000/09/30(土) 00:04
ページマップの変更だけでは、完全なreallocの実現は困難だけど、
ページサイズ以上のヒープブロックであれば、ある程度、効率よく出来そうだけどね。
まぁ、少なくとも、malloc+freeとイコールではないでしょ。
この辺は、実装依存だから、なんとも言えませんが。

どっちにしろ、細かい単位で煩雑にヒープの確保、再確保、開放してると、
フラグメントも完全には避けられないし、パフォーマンスも悪いです。
まとめて確保して、うまく振り分けたほうが効率いいですな。
62名無しさん@お腹いっぱい。
>>60
VC++5だか6だか辺りから「小ブロックヒープマネージャ」が入って
いた気がするが...