[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 2chのread.cgiへ]
Update time : 04/23 14:20 / Filesize : 191 KB / Number-of Response : 803
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C++相談室 part94



1 名前:デフォルトの名無しさん mailto:sage [2012/02/18(土) 06:07:36.70 ]
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

前スレ
C++相談室 part93
toro.2ch.net/test/read.cgi/tech/1324922431/

このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.77【環境依存OK】
toro.2ch.net/test/read.cgi/tech/1323692486/

■長いソースを貼るときはここへ。■
 codepad.org/
 ideone.com/

751 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 19:04:47.26 ]
>>730
memset か std::fill に決まってるジャン(std::fill_n は警告出る事あるのでやはり使わない)
= { 0 } は可読性に劣るとも思うしね
初期化忘れか意図的な 0 クリアかが
コメント残さないと確実に伝えられないから
最初の 0 がある意味マジックナンバーじみているのも気持ち悪い

752 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 19:30:08.71 ]
普通構造体に = { 0 }してたら初期化だと思うがな。
あと組み込み向けのしょぼいコンパイラーだとこっちの方が早いことがある
逆にmemsetの方が早いってのは聞いたことないけどね

753 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 19:43:36.33 ]
>>751
それ初期化じゃないじゃん。
それに
={};
で初期化し忘れと読み取るアホはおらんよ。

754 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:04:39.00 ]
= { }; は C で使えないよね

755 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:09:06.33 ]
使えないけど、それがどうかしたの?

756 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:13:57.52 ]
知らない人が結構いそうだから使いたくないわ

757 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:24:10.37 ]
>>747
>reallocで1度コピー
領域拡大時であってもrealloc()だとコピーが起きないことがある
縮小時はもちろんほぼ常に起きないことが期待できる

>replacement newでもう一度初期化。
誰も2回も初期化しないわけだが
つかデフォルトのnewは使えば必ずメモリ確保してから初期化するのに対し、
プレースメントnewはそれ自体はメモリ確保しないから、
メモリがすでに確保されている場合はより早いの
ワカル?


758 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:38:05.66 ]
>>757
理解出来てないなら黙ってろ

759 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:38:21.85 ]
>>748
ソウジャナイ
破壊的代入が本質的(それ無しには何事も進まない)のが命令型言語、
非破壊的代入で全て済ますのが関数型言語
前者はチューリングマシン、後者はλ式をそれぞれ数学的基礎とする

一方で書けるアルゴリズムは他方でも書けるという意味で両者の計算能力は等価
ただし得手不得手はもちろん違う




760 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:41:11.32 ]
>>758
どこらへんがおかしいのかkwsk

つかrealloc()が勝手にコピーするとオブジェクト必ず壊れるとか思ってる?
std::vector<T>の要素型として使える型Tについてはそれは心配せんでええ


761 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:50:37.51 ]
>領域拡大時であってもrealloc()だとコピーが起きないことがある
>縮小時はもちろんほぼ常に起きないことが期待できる

どういう理屈なんだ?

762 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:51:25.25 ]
>>759
お前が言ってるのは手続き型だろ

763 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 20:54:06.90 ]
>>759
関数型は、演算式と制御文を全て関数で記述する事を目的とした言語
破壊的代入が無いというだけだと宣言型とダブるので、
破壊的代入が無い = 関数型というのはおかしい

764 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:03:04.70 ]
>>761
K&Rの終わりぐらいに書いてあるmalloc()の実装例でも読めばおk
サイズs1、s2の領域がこの順で隣接しており、s2が開放されたなら
サイズs1をサイズs1+s2までコピー無しで拡大することができる
(※簡単のため管理用のヘッダサイズは無視)

>>762
関数型言語であってもリストで手続き(順序的な処理)を表わせるから
手続き型/非手続き型の区分は命令型/関数型の切り口とは異なる別概念
Prologみたいに処理の順序が平に書かれない言語を非手続き型といい、
手続き型というのはそれの対義語


765 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:12:41.32 ]
>>763
宣言型というのは、ようわからんが非手続き型っていうのとほぼ同義ジャネ?
破壊的代入無しでチューリングマシンの計算能力と等価な言語、
といえば多分λ式ベースの言語(つまり関数型言語)しかないんじゃないかなあ、、
なお、関数型は、(関数で)新しい関数を作り出すことしかしない故に関数型


766 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:12:47.96 ]
>>764
mallocじゃなくreallocの内部の話なんだけど
実際コピーしない処理系が存在するのか?
gccのreallocはソース公開されてるがコピーしてる
実際どの処理系がしてるんだ?
普通に考えてもmalloc内部の実装に依存するreallocなんてクソだろ

767 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:15:18.80 ]
>>764
>関数型言語であってもリストで手続き(順序的な処理)を表わせるから
>手続き型/非手続き型の区分は命令型/関数型の切り口とは異なる別概念
>Prologみたいに処理の順序が平に書かれない言語を非手続き型といい、
>手続き型というのはそれの対義語

お前だけの常識で語られてもなぁ

768 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:32:45.54 ]
>>766
realloc()をmalloc()と別階層とすべきですかそうですか、、
コピーを生じない処理系の具体例については、
少なくとも下記コードをVS2010で走らせるとp1 == p2なんだけど?
  void* p1 = malloc(1000);
  void* p3 = malloc(1000);
  free(p3);
  void* p2 = realloc(p1, 2000);
  cout << "p1=" << p1 << ", p2=" << p2 << endl;

glibcのソースをよく読みなおすことをお勧めする

>>767
漏れだけの常識がどうかはようわからんが、そうなの?
>764で妥当だと思うがなあ〜


769 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:35:05.31 ]
で、いつまでちんたらちんたら続くんだ?



770 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:36:14.02 ]
>>760
おいおい、オブジェクト領域でreallocなんか使ったら壊れるだろうがw

ポインタ関係が全部おかしくなるわ。

771 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:38:31.10 ]
>>768
サイズ変更が「可能な場合」はコピーされない。不可能な場合はコピーされる。


コピーされる場合はありえるんだが、たまたま特定環境化で動作するから使っていいとかアホの極み。ドシロウト。

仕事でそれ使ってたらリアルで背任でクビになるようにもっていく。

772 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:39:33.64 ]
>>768
そのコードじゃそりゃそうだろ。
つかそのコードはreallocの問題じゃねぇ。言い方悪かも試練が偶然だ。
解放された領域をもう一度使用してるのは意図して書けばできる事だが、
reallocが同じ領域であることを知っててコピー処理を省略してるかどうかは別問題。


773 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:40:57.09 ]
>>770
>ポインタ関係が全部おかしくなるわ。
ポインタを含まないか、ポインタを含んでも指す先が移動対象でないなら
そういうオブジェクトは勝手にコピーされても無問題でしょ?
で、std::vector<T>の要素型として使えるような型Tのオブジェクトなら、それは成立している、というしくみ


774 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:45:00.34 ]
>>771>>772
まあ冷静に
コピーされる場合がありえるし、コピーされる/されないを
realloc()の呼び出し側で制御できないのは承知していますから
ただ、std::vector<T>の要素型として使えるような型Tのオブジェクトなら、
プレースメントnewをうまく使って安全にrealloc()で領域管理できるという話

775 名前:デフォルトの名無しさん [2012/04/22(日) 21:54:51.43 ]
マジレスしないでニヨニヨ笑ってる人が絶対いる悪寒
あまりにも不自然すぎる

776 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:56:42.25 ]
>>774
二重コピーされる分realloc使うのが無駄なのは事実だろ
まだmalloc, free, mallocしてreplacemente new呼んだ方がマシだ

777 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:06:36.44 ]
>>776
ちょっと前のレスから気になってたが、replacement newってなんぞね?
また、realloc()の呼び出し1回で同一オブジェクトのコピーが2回起きるみたいな書き方も気になるが、
それっていつどういうシチュで??

もし>738のようなコピーコンストラクタ呼び出しの回数のことを言ってるのなら、
それはrealloc()一回につき同一オブジェクト当たり1回以下にできる
(realloc()がコピーするかしないかや呼び出し下で制御できないが、
 領域の移動があったかどうかは呼び出し元で判定でき、移動しなかったオブジェクトについて呼ぶ必要はないため。)


778 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:08:51.64 ]
その程度の処理が問題になるなら動的確保自体使わなきゃいいだろ。

まずはEffectiveC++でも嫁やザコ

779 名前:777 mailto:sage [2012/04/22(日) 22:10:35.64 ]
スマン訂正
std::vector<T>の要素型として使えるような型Tのオブジェクトなら、
勝手にコピーされても何もする必要がないから、領域の移動は関係なかったな、、




780 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:14:06.10 ]
>>777
reallocで1回、new( buffer ) Type();で1回、合わせて2回だろ。

781 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:23:58.97 ]
>>773
自分自身をさすポインタをもつ場合、コピーコンストラクタ/operator=を正しく書けばvectorに入れられるが、メモリコピーでは正しく処理できない。

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

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

784 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 22:45:14.75 ]
>>782
手間が増えるだけでreallocするメリットねぇじゃねぇか

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


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

787 名前:デフォルトの名無しさん mailto:sage [2012/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 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 23:09:34.08 ]
不毛だ

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



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

791 名前:デフォルトの名無しさん mailto:sage [2012/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 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 01:26:27.20 ]
>>779
vector の要素型に realloc() で発生しうる memcpy() への耐性なんて要求されてないんだが

793 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 01:43:35.76 ]
>>791
realloc内部でfreeされるがな

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

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

796 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 03:05:19.97 ]
もうほっとけよ

797 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 03:19:14.56 ]
class MyClass{
public:
bool hoge();
}

MyClass instance;

があるとして、

「instance.hoge()」

が与えられたときに、

「MyClass::hoge(),&instance」

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

798 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 04:24:58.06 ]
メンバ関数ポインタ

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



800 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 06:50:18.40 ]
「&MyClass::hoge,&instance」が欲しい理由じゃないのか?

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

802 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 12:53:08.14 ]
std::bindとstd::functionでおk






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<191KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef