C++相談室 part94at TECH
C++相談室 part94 - 暇つぶし2ch782:デフォルトの名無しさん
12/04/22 22:34:14.86
>>780
普通そうはならないべ

サイズs1の領域が確保済みで、realloc()でそのサイズをs1+s2に拡大する場合、効率的な実装なら、まず>764(の前半)のようなケースでは実質コピー0回。(空き領域リンクリストの繋ぎ替えが起きるだけ。)
運が悪ければ、領域の移動を要し、サイズs1の部分のみコピーされる(コピー1回)。
ここには今の想定だと構築済みオブジェクトが入っているが、コピー安全なオブジェクトなのでそれ以外なにもしなくていい。つまり、コピーはオブジェクト毎に高々1回。

で、new(p) Type(); が必要なのは、新規に確保されたサイズs2の領域だけ。よって、2回コピーされるオブジェクトは生じない。

なお、細かいことを言えば、new(p) Type()はアドレスpについてType型のデフォルトコンストラクタを呼び出すだけなのでコピーではない。
また、Typeのデフォルトコンストラクタが全フィールドを確実に初期化する保証があるなら
new(p) Type(); と書くより new(p) Type; の方がよろしい。(0 fillが省略されるから早くなる。いつの規格からかは知らん。)

>>781
ああすまん、それはそうね。

783:デフォルトの名無しさん
12/04/22 22:41:23.02
>>782
>サイズs1の領域が確保済みで、realloc()でそのサイズをs1+s2に拡大する場合、効率的な実装なら、まず>764(の前半)のようなケースでは実質コピー0回。(空き領域リンクリストの繋ぎ替えが起きるだけ。)

この前提が間違ってるって何度も指摘されてるだろ

784:デフォルトの名無しさん
12/04/22 22:45:14.75
>>782
手間が増えるだけでreallocするメリットねぇじゃねぇか

785:デフォルトの名無しさん
12/04/22 22:45:21.40
>>783
>何度も指摘
kwsk
すくなくとも、(たまたまかどうかはともかくとして)realloc()前後で領域が移動しなかった実例が>768にあるわけだが
これって呼び出し前後でアドレスが変わらない部分についてもrealloc()は律儀にコピーしてるってことなの??
>738おすすめのヒープメモリ管理方式を聞いてみたい気がするカモメ、


786:デフォルトの名無しさん
12/04/22 22:49:16.76
>>785
ことなの?じゃなくコールスタック追いかけるか
逆アセしてみろよ。memcpy呼ばれてるだろ

787:デフォルトの名無しさん
12/04/22 23:06:31.08
>>786
VS2010のデバッグモードでmemcpy()にブレークポイントしかけて見て見たが、
>768のコードにおける4行目
void* p2 = realloc(p1, 2000);
の呼び出し中のmemcpy(src, dst, count)の呼び出し回数は3回、ただしcountはどれも2だったべ
これはリンクリストか何かのコピーじゃねーの?
(>783の指摘どおりだとしたら1000バイト級のmemcpy()が起きないとおかしいが)

で、仮に万が一>783の指摘が正しかったとして、2回コピーされる件はどうなったのよさ?
主張を取り下げて>782で納得?


788:デフォルトの名無しさん
12/04/22 23:09:34.08
不毛だ

789:デフォルトの名無しさん
12/04/22 23:27:27.52
>>787
2回コピーは俺だが。新しい領域のみコンストラクターの結果を
コピーするんならたしかにコピーは1回だな。そこは納得するよ。

790:デフォルトの名無しさん
12/04/22 23:45:41.19
>>787
URLリンク(codepad.org)
そもそも、同じアドレスだからと言って一旦解放された領域に
同じ値が入ってるとも限らんからな
このコードVSにコピペして実行してみ

791:デフォルトの名無しさん
12/04/23 01:13:06.56
>>790
ちょっwwwwwwおまwwwwwwwwww
例示のコードはrealloc()とは話が違うわけだが
そりゃーfree()で本当に解放してしまった領域には誰に何書かれるかわからんでしょうよ
(別スレッドあり、デバッグビルドのfree()だと丁重に0xccccccccで埋めてくれたりすることあり。
 セキュリティー目的で埋めるライブラリもあるかも試練、)

なんつーか>768のコードの意図が伝わってないようだけど、
K&R式なmalloc()およびrealloc()な実装の下で>768をシングルスレッド状況で走らせると
>782で言うコピー0回な挙動になるんすよ
>768は、その挙動を演出するために、使用中の領域(p1)とは関係ない領域(p3)を一旦malloc()後にfree()してるだけ
p1が指す領域は一貫してfree()されない。

792:デフォルトの名無しさん
12/04/23 01:26:27.20
>>779
vector の要素型に realloc() で発生しうる memcpy() への耐性なんて要求されてないんだが

793:デフォルトの名無しさん
12/04/23 01:43:35.76
>>791
realloc内部でfreeされるがな

794:デフォルトの名無しさん
12/04/23 02:08:56.95
だから、C++ならnewだけを使えよ。
わざわざ危険を犯そうとする冒険者になることは、ない。

795:デフォルトの名無しさん
12/04/23 02:19:24.31
newの使い方よりも
newそのものの速度が問題になる状況って
どんな状況だ?

796:デフォルトの名無しさん
12/04/23 03:05:19.97
もうほっとけよ

797:デフォルトの名無しさん
12/04/23 03:19:14.56
class MyClass{
public:
bool hoge();
}

MyClass instance;

があるとして、

「instance.hoge()」

が与えられたときに、

「MyClass::hoge(),&instance」

を返すようなマクロは作れませんでしょうか?

798:デフォルトの名無しさん
12/04/23 04:24:58.06
メンバ関数ポインタ

799:797
12/04/23 04:25:55.73
なんとか、
「instance.hoge()」
という記述から、メンバ関数ポインタとthisポインタを取得したいんですよね。。。

800:デフォルトの名無しさん
12/04/23 06:50:18.40
「&MyClass::hoge,&instance」が欲しい理由じゃないのか?

801:797
12/04/23 12:43:53.90
これが欲しい理由は、一度&MyClass::hogeと&instanceを保存しておいて、
あとでそのメンバ関数を呼び出したいんです。
使う箇所が多いので、テンプレートとかでなんとかできないかと思いました。

802:デフォルトの名無しさん
12/04/23 12:53:08.14
std::bindとstd::functionでおk


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch