C++相談室 part63

このエントリーをはてなブックマークに追加
672デフォルトの名無しさん
Exceptional C++って本が評判良いようなので、買ってみましたが
newのエラーチェックは必要ないとかとんでもないことが書いてあったので本棚の奥に片づけました

で、タイトルよく見るとExceptional C++ Styleだったので偽物掴まされたのかと思ったんですが
書いてる人同じなんですね

Styleの方はダメ本ですが、Exceptional C++ってのは大丈夫なんですか?
673デフォルトの名無しさん:2008/10/29(水) 18:13:45
>newのエラーチェックは必要ないとかとんでもないことが書いてあったので本棚の奥に片づけました
お前がとんでもない。
674デフォルトの名無しさん:2008/10/29(水) 19:36:58
>>672
int* p = new int;
if (p == 0) ←これが要らないっていう話?
675デフォルトの名無しさん:2008/10/29(水) 19:39:00
なぜいらないのかも、なぜ使われていたかも両方説明されてたと思うんだけどな
676デフォルトの名無しさん:2008/10/29(水) 19:40:29
627は本をちゃんと読めない子なんですね
677デフォルトの名無しさん:2008/10/29(水) 19:41:44
>>674
いいや
bad_allocを捕まえることもnew(nothrow)をヌルチェックすることも意味がないと書いてある
メモリは遅延確保するからnewは常に成功するとか書いてる
ひどすぎる
678デフォルトの名無しさん:2008/10/29(水) 19:42:23
676は数字をちゃんと読めない子なんですね
679デフォルトの名無しさん:2008/10/29(水) 19:44:01
>>677
それは Linux を含む一部の環境では実際正しい。
というか、malloc じゃなくて new でその説明があった?
680デフォルトの名無しさん:2008/10/29(水) 19:46:49
>>679
C++の本だもん、もちろんnewの話ですよ
でも滅多に起こらないとしても、環境によっては絶対に起こらないとしても、
それでもやるのがエラーチェックでしょう?

著者の姿勢に疑問を感じざるを得ないです
681デフォルトの名無しさん:2008/10/29(水) 20:07:24
>>677
参考までにどこのページ?
682デフォルトの名無しさん:2008/10/29(水) 21:05:17
>>680
それは哲学の問題であって、プログラミングの問題ではないよ。
683デフォルトの名無しさん:2008/10/29(水) 21:11:50
>>681
気になったので、手元の本で調べたら p.177 辺りの話のようだ。
久しぶりに読んでみたが、個人的には、真っ当な事が書かれてると感じた。
ところで new に失敗した時、一体どんな処理をするのだろうか?
メモリ枯渇が原因だとして、そんな環境で打つ手があるのか。
684デフォルトの名無しさん:2008/10/29(水) 21:24:57
>>683
他(ユーザーのデータやシステム)に致命的被害を及ぼしたりしないように安全に終了する。
可能であれば、自分が扱っているデータも安全に保存した上で。
685デフォルトの名無しさん:2008/10/29(水) 21:27:59
予め余計に確保しておいてそっちを使うとか
686デフォルトの名無しさん:2008/10/29(水) 21:46:59
>>684
それは普通に組んでれば例外がさかのぼる途中で実現される気がする

newで失敗したときにいろいろしたければnew_handlerでやればいいし、正直bad_allocが投げられたらオワリなんじゃ?
687デフォルトの名無しさん:2008/10/29(水) 21:55:45
その前のページ(p.176)に「エラーチェックしないなんてとんでもないこと書いてる」っていう人も居るとは思うがってわざわざ書いてるじゃん。

ちなみにその章の Summary の訳。

>nothrow new の使用は避けること。通常の例外を送出する new と比べて、最近では意味のある利点がないこと、
>また大抵はより悪い失敗時の特徴を持つからである。
>
>いつくかの理由から、とにかく new の失敗をチェックしようというのはあまり利点がないということは覚えておくべきである。
>
>メモリの枯渇について正当な懸念があるなら、チェックしていると考えているものがチェックできているか気をつけよう。
> - メモリが使用されるまでメモリ確保しないシステムでは、new の失敗をチェックすることは大抵役に立たない。
> - 仮想メモリシステムでは、new の失敗に遭遇することはまれか全くない。なぜなら仮想メモリが枯渇する遥か以前の
> 時点で、大抵スラッシングが発生し管理者がプロセスを kill し始めるからである。
> - 特別な場合を除いて、new の失敗を検出した場合でも、本当にメモリが残されていないなら、できることは多くはない。
688デフォルトの名無しさん:2008/10/29(水) 22:01:25
とある官庁向けのシステムで、メモリ不足のときにご丁寧にダイアログでメッセージを出すプログラムを書いてきた
シナ系ソフトハウスがあった。実際にメモリ不足の状況を作ってやったら、ダイアログを出そうとする行為自体が
メモリ確保エラーを起こすらしくて画面を埋め尽くす勢いでダイアログが開いていき、メモリスワップに突入。
メモリ不足の状況を解除してからダイアログの増殖が止まるまでに20分掛かったのはいい思い出w

教訓。実際にメモリ不足の状況に陥ったら、できることは高が知れている。
689デフォルトの名無しさん:2008/10/29(水) 22:08:37
やらない方がマシだとは思うが終了処理とかのために予め5MB位最初に確保しておき
メモリ不足になったら開放してメモリをあけるみたいなテクニックを聞いたことがある。
690デフォルトの名無しさん:2008/10/29(水) 22:13:05
メモリもだが、ファイルディスクリプタ枯渇も面倒
エラーログはこうとしてファイルをオープンしようとするが失敗
そのエラーのログをさらにはこうとして…(以外同文
691デフォルトの名無しさん:2008/10/29(水) 22:33:43
エラーログ出力のエラーログ出力をするヴァカがここにもまた一人
692デフォルトの名無しさん:2008/10/29(水) 22:33:47
>>688
俺も、実際に似たような事例に遭遇したので、>>683 を書いた。
エラーチェックは良い事だが、その実効性を検証しないと意味がないし、メモリ確保の問
題は OS が深く絡むので、OS がするより良い対応をアプリケーションで行うのは非常に難
しく、副作用の方が心配になる。
もし大量のメモリ確保が心配なら、API で空きメモリ量を得て、new する前に妥当性チ
ェックする方が真っ当だと思うし ( チェック直後に枯渇した場合は事故とする )。
693デフォルトの名無しさん:2008/10/30(木) 01:36:37
xxx* p = new xxx;
if (p == 0) {*}←これ

実際に、これが実行された経験ある奴いるの?
1Tバイトぐらいのメモリよこせと言えば実行さるるのかな
694デフォルトの名無しさん:2008/10/30(木) 01:39:39
>>693
まともな処理系なら、bad_allocが飛ぶので、絶対に実行されることはない。
695デフォルトの名無しさん:2008/10/30(木) 01:50:46
賢い処理系なら最適化として if を丸ごと削除してもいいだろう。