◀ANSI版開発トップへ
  • 4235 システムリソース不即時のエラー処理
    • 4236 Re:システムリソース不即時のエラー処理
      • 4237 Re2:システムリソース不即時のエラー処理
    • 4239 Re: システムリソース不即時のエラー処理
      • 4240 Re2: システムリソース不即時のエラー処理
        • 4241 Re3: システムリソース不即時のエラー処理
          • 4245 Re4: システムリソース不即時のエラー処理
            • 4246 Re5: システムリソース不即時のエラー処理
              • 4247 Re6: システムリソース不即時のエラー処理
                • 4248 Re7: システムリソース不即時のエラー処理
          • 4249 リソース不足時 CMemory クラスのふるまいの件
            • 4273 Re5: システムリソース不即時のエラー処理
              • 4276 Re6: システムリソース不即時のエラー処理
                • 4278 Re7: システムリソース不即時のエラー処理
              • 4277 Re6: システムリソース不即時のエラー処理
              • 4279 Re6: システムリソース不即時のエラー処理
            • 4281 Re:リソース不足時 CMemory クラスのふるまいの件
              • 4285 Re2:リソース不足時 CMemory クラスのふるまいの件
                • 4291 Re3:リソース不足時 CMemory クラスのふるまいの件
                  • 4292 Re4:リソース不足時 CMemory クラスのふるまいの件
          • 4261 システムリソース不足時の例外処理の件
            • 4283 Re:システムリソース不足時の例外処理の件
              • 4287 Re2:システムリソース不足時の例外処理の件
              • 4288 Re2:システムリソース不足時の例外処理の件
  • [4235] システムリソース不即時のエラー処理 ラスティブ 2006年01月30日 01:13

    これまた唐突で恐縮です.

    ・1999.06.14 □ ----.--.-- システムリソース不足時のエラー処理が不十分

    これについて, CMemory, CDocLine, CLayout 周りだけ見て回ったところ,

    ・malloc() realloc() のラッパークラス or 関数を作る.
    ・new, new[], delete, delete[] 演算子を malloc() free() で実装しなおす.
    ・これらを基にして,「メモリが足りません」状態を統一的に捕捉する.

    とすると, かなり大掛かりで大胆ですが, 解決するのではないかと思いました(感想).
    ウインドウ操作系のコードをまったく読めない私が見てもどうしようもありませんが.
    • [4236] Re:システムリソース不即時のエラー処理 (全略) 2006年01月30日 23:35

      > ・malloc() realloc() のラッパークラス or 関数を作る.
      > ・new, new[], delete, delete[] 演算子を malloc() free() で実装しなおす.
      システムリソースとの関係がよく分かりませんがメモリーリークの対応策でしょうか?
      メモリリークの対策にmallocとfreeを使うのは本末転倒だと思うのですが
      • [4237] Re2:システムリソース不即時のエラー処理 ラスティブ 2006年01月31日 00:40

        >システムリソースとの関係がよく分かりませんがメモリーリークの対応策でしょうか?
        >メモリリークの対策にmallocとfreeを使うのは本末転倒だと思うのですが

        何かのオブジェクトを作成する際,
        (今時は滅多に起きない, という意味で) 高がメモリ不足ごときに,
        try-catch ブロックみたいなのをいちいち書くのも うっとうしいかと思いまして.
        メモリ確保の手段を統一するという目的も兼ねて,
        new delete 関係の演算子をオーバーライドして,
        「メモリを確保できませんでした」なんてことを言わせなくする,
        なんてことを考えてたのですが,
        …メモリリークの問題に対しては本末転倒でした.

        言葉足らずですみません.
    • [4239] Re: システムリソース不即時のエラー処理 げんた 2006年01月31日 23:20

      >・これらを基にして,「メモリが足りません」状態を統一的に捕捉する.
      統一的にというのは
      →ファイルを開く途中ならキャンセルして終了
      →文字列操作・コマンド処理なら元に戻す
      ということでしょうかね.

      ただ全てを一カ所で捕捉できればいいのですが,場合によっては元の状態に戻さなくてはならなかったりとかあるように思います.
      (Copyで半分貼り付けたところで溢れた場合に戻すかどうかとか)

      そういえばこのエディタは無限Undoを謳っていますが,これはUndoバッファを永遠に解放しないと言うことなのでずっと使っていたらいつかメモリ不足になるような...違ったかな.
      • [4240] Re2: システムリソース不即時のエラー処理 ラスティブ 2006年02月01日 08:33

        > 統一的にというのは
        > →ファイルを開く途中ならキャンセルして終了
        > →文字列操作・コマンド処理なら元に戻す
        > ということでしょうかね.

        呼び出し側に告知するだけでも, 効果的かと思いまして.

        > ただ全てを一カ所で捕捉できればいいのですが,
        > 場合によっては元の状態に戻さなくてはならなかったりとかあるように思います.
        > (Copyで半分貼り付けたところで溢れた場合に戻すかどうかとか)

        自由領域アロケーター (CMemory クラスや malloc とか) から例外を受け取れるように,
        仕様を変更するのが良いかと思ったのですが,
        既存コードとの折り合いからすると,
        なんだか難しそうなので…

        復元しようの無い場所で「メモリが足りません」状態に
        陥った場合, いっそのこと致命的エラー扱いということで,
        メモリ不足で落ちそうな場所に出来れば限定して,
        new, delete 演算子をオーバーロードさせておいて,
        その例外処理ハンドラによって編集中のファイルを
        復元時のためにディスクへ退避させて,
        プロセスを仕方なく消す方向で処理するとか…
        なら, 出来なくなさそうかなーと, 想像しています.
        • [4241] Re3: システムリソース不即時のエラー処理 (全略) 2006年02月01日 21:07

          ▼ ラスティブさん
          > 自由領域アロケーター (CMemory クラスや malloc とか) から例外を受け取れるように,
          > 仕様を変更するのが良いかと思ったのですが,
          > 既存コードとの折り合いからすると,
          > なんだか難しそうなので…
          冒頭で言われていたのはmallocやHeapAllocとかのラッパー関数から
          失敗した場合bad_alloc例外を投げたりする、と言うことだったのでしょうか(^-^;?

          > 復元しようの無い場所で「メモリが足りません」状態に
          > 陥った場合, いっそのこと致命的エラー扱いということで,
          > メモリ不足で落ちそうな場所に出来れば限定して,
          > new, delete 演算子をオーバーロードさせておいて,
          > その例外処理ハンドラによって編集中のファイルを
          > 復元時のためにディスクへ退避させて,
          > プロセスを仕方なく消す方向で処理するとか…
          > なら, 出来なくなさそうかなーと, 想像しています.
          SetUnhandledExceptionFilterで例外ハンドラを設定しておいて、そこで無理矢理保存を行うとか、、、
          自家用のビルドでやっていますが、それなりに機能しています

          # もっともnewすら失敗するようなテンパった状況では保存処理すら失敗するかもしれませんが^^;
          • [4245] Re4: システムリソース不即時のエラー処理 ラスティブ 2006年02月07日 06:15

            新しく作った CMem クラスをブリーフケースに上げときました. (バグがないことを願いつつ... CMem.zip )
            下手すると標準ライブラリの vector クラスとダブってしまうので,
            Sakura 向けに, 機能は必要最低限.

            これを基にして文字列操作部分を作れば,
            少なくとも文字コード変換中に落ちることはなくなる
            …かもと思ってますけど, 過去ログにもありましたが,
            モジュールを CString, CCharTypes, とかに分けないとですね…;;

            > SetUnhandledExceptionFilterで例外ハンドラを設定しておいて、そこで無理矢理保存を行うとか、、、

            実装できてません;;
            かなり力量不足でした.

            過去ログより:

            Unicode 化について (dev:2969)
            > ・管理するデータ専用の型(例:MOJI)を新たに作成して、それで書き換える。
            >  (ただし、実態はwchar_tである)

            最後尾につける番兵を2バイトに増やしました (バイナリデータに対しては無意味ですが一応).
            ここで言ってる「管理するデータ」ってのがいまいち解りませんが...
            BYTE 単位で統一しました. 可変長マルチバイト文字を処理するのに困ると思いますし.

            速度について (dev:1318)
            > … 削除・挿入時にいったんメモリを別に確保して
            > そちらにコピーし、最後にCMemoryにSetDataSzしていること。
            > この辺をCMemoryにやらせればメモリ転送が減るような気が...

            memcpy memmove に毛が生えたようなもので対応しました.
            挿入なんていう高尚なことはしないで,
            ただただ上書きするだけです.
            実際に計ったわけではないですが,
            たぶん超遅いので使い物になるかどうか.
            • [4246] Re5: システムリソース不即時のエラー処理 ラスティブ 2006年02月07日 21:35

              自己レス
              > 新しく作った CMem クラスをブリーフケースに上げときました.
              > (バグがないことを願いつつ... CMem.zip )
              すみません.
              都合により引数の順序を変更しました. → CMem1_1.zip
              お間違いのありませんよう…
              • [4247] Re6: システムリソース不即時のエラー処理 げんた 2006年02月08日 01:03

                CMem拝見しました.
                ところで,これとここまでの異常時に保存くらいは出来るかどうかという話とどうつながるのかがわからなかったんですが,説明して頂けませんか?どういった点が大きなポイントなのかが見ただけではよくわからなかったので.
                • [4248] Re7: システムリソース不即時のエラー処理 ラスティブ 2006年02月08日 13:58

                  > これとここまでの異常時に保存くらいは出来るかどうかという話とどうつながるのか

                  >> SetUnhandledExceptionFilterで例外ハンドラを設定しておいて、そこで無理矢理保存を行うとか、、、
                  >
                  >実装できてません;;
                  >かなり力量不足でした.

                  と書いたように, 例外機構を上手くデザインするまでにはこぎつけなかったというオチ…. それとは別件で, 過去 CMemory に要求された事項をできる範囲で施しました.

                  確かに支離滅裂…;; すみません.

                  > どういった点が大きなポイントか

                  CMemory の AllocBuffer と比較するなら「失敗」を呼び出し側に報告することができる点と, オブジェクトサイズを表すのに typedef unsigned int size_t 型を使っている点. CMemory は大変保守性が悪そうなので... その将来を考えて CMemory と別個に書きました. CMemory は Java で言うインターフェース見たいに機能してくれると願って.

                  板汚し失礼しました.
          • [4249] リソース不足時 CMemory クラスのふるまいの件 ラスティブ 2006年02月09日 02:05

            >>> SetUnhandledExceptionFilterで例外ハンドラを設定しておいて、そこで無理矢理保存を行うとか、、、

            CMemory が行うメモリ管理の詳細を CMem クラスで隠す. もし CMem 傘下の関数が Error を投げてきたら CMemory は...

            1. 文字コード変換処理, 置換処理なら「失敗しました」と戻り値で報告,
            2. AllocBuffer, Set* 系, Append* 系なら 内部エラーとして (例えば) CError_Fatal を再び投げる,
            までは考えられます.

            >・1999.06.02 □ ----.--.-- 巨大なテキスト全体を「E-Mailコード変換」したら落ちたけん

            16MBほど (全部 ASCII文字) のファイルを開いて変換して, 再現しませんが(ASCII だから? でないとすれば直ってるのかもしれない), 1 の手でこれに対処できたらひとまず嬉.
            それに関連して, MemSJIStoJIS って, 文字を一つ一つコピーしてから処理して, また同じ位置に戻す仕組みになってるんですけど... 実のところどうなんでしょう.
            • [4273] Re5: システムリソース不即時のエラー処理 ラスティブ 2006年02月20日 16:40

              > CMemory が行うメモリ管理の詳細を CMem クラスで隠す.
              → Developer / Source / CMem_and_CMemory.zip

              カット&ペーストするときに改行を含めると,
              なぜかごみまでペーストされるようになってしまいました;;
              かなり使い物にならないのですが,
              意外なところに副作用が出て見当が付かないので,
              どなたか詳しい人, 添削してくだされば幸いです m(_ _)m
              • [4276] Re6: システムリソース不即時のエラー処理 げんた 2006年02月21日 02:24

                >どなたか詳しい人, 添削してくだされば幸いです m(_ _)m
                添削ではありませんが,Pasteデータを改行で分離しているのは
                CDocLineMgr::InsertData_CDocLineMgr()
                あたりなので,この辺を調べてみては?
                • [4278] Re7: システムリソース不即時のエラー処理 ラスティブ 2006年02月21日 12:43

                  ▼ げんたさん
                  > CDocLineMgr::InsertData_CDocLineMgr()
                  > あたりなので,この辺を調べてみては?

                  アドバイスありがとうございます.
                  その辺りも視野に入れながらチェック中です.
                  いちばん疑わしいのは当然ながら
                  CMem クラスによる実装部分なのですが;;
              • [4277] Re6: システムリソース不即時のエラー処理 ラスティブ 2006年02月21日 07:21

                > CMemory が行うメモリ管理の詳細を CMem クラスで隠す.
                → Developer / Source / CMem_and_CMemory_0.1v.zip

                ・CMem の ExchangeFor() 関数のつくり間違い系バグを修復.
              • [4279] Re6: システムリソース不即時のエラー処理 ラスティブ 2006年02月21日 16:29

                > CMemory が行うメモリ管理の詳細を CMem クラスで隠す.
                → Developer / Source / CMem_and_CMemory_1.0v.zip

                ・AllocBuffer() の意味を取り違えて CMem 側で Resize() と解釈していたのを, Expand() に変更することで修復完了.
                追記:
                スクロール時に起こる CPU ファンの音は少し静かになりましたが...
                以前からの伝統的な AllocBuffer ではなくなった可能性がありますのでご注意ください.
                追記その2:
                >スクロール時に起こる CPU ファンの音は少し静かになりましたが...
                大嘘でした. ウインドウ領域が小さかっただけというオチ.
            • [4281] Re:リソース不足時 CMemory クラスのふるまいの件 ラスティブ 2006年02月22日 08:43

              > 1. 文字コード変換処理, 置換処理なら「失敗しました」と戻り値で報告,

              この件について取り掛かりたいのですけれど, どうも水面下で CEncoder クラスというのがあるようなのでスキップします.
              他のクラスと帳尻が合わなくなるという残念な事態を避けるべく.
              # 過去ログにそのクラスのソースコードがアップされてありましたけど, 覗けないようです;;
              • [4285] Re2:リソース不足時 CMemory クラスのふるまいの件 dskoba 2006年02月23日 01:09

                > この件について取り掛かりたいのですけれど, どうも水面下で CEncoder クラスというのがあるようなのでスキップします.
                > # 過去ログにそのクラスのソースコードがアップされてありましたけど, 覗けないようです;;

                http://www2.wbs.ne.jp/~dskoba/products/

                基本的なエンコードのみ出来ています。メールヘッダのデコードのあたりで止まってます。
                大文字<-->小文字,ひらがな<-->カタカナ,なども加えようかと思ってますが手づけずです。
                • [4291] Re3:リソース不足時 CMemory クラスのふるまいの件 ラスティブ 2006年03月07日 07:03

                  ▼ dskobaさん
                  > http://www2.wbs.ne.jp/~dskoba/products/
                  >
                  > 基本的なエンコードのみ出来ています。メールヘッダのデコードのあたりで止まってます。
                  > 大文字<-->小文字,ひらがな<-->カタカナ,なども加えようかと思ってますが手づけずです。

                  → ブリーフケース/Developer/Source/sdiff_2006-02-19_CMemFixed_3v.zip

                  いろいろまだ途中ですが一旦アップ.

                  ・CEncodingConverter.cpp で文字コード変換ルーチンを差し替えた.
                  (試行錯誤の末, CEncoder は本家のものとは別物となってしまいました. なんというか, 申し訳ありません.)
                  ・スペース→タブ変換の仕様を少し変えた.(emacs 風にした.)
                  (不評でしたら戻します;;)
                  ・文字コード判別に, wchar 版 CMemroy にあったアイデア(NUL バイトの数を数えるというやつ)を取り入れた.
                  ・メモリ不足になるとbad_alloc 例外が確実に飛んでくるように(たぶん)なった.
                  ・new 演算子の修繕コードを CMem クラスへ組み入れて, CSakuraObjectBase.h は消滅し, CError.h となった.
                  ・charcode.h が大きく変わった.

                  本格的な例外処理は, 呼び出し側で実装することと相成りました….
                  • [4292] Re4:リソース不足時 CMemory クラスのふるまいの件 ラスティブ 2006年03月07日 22:18

                    > → ブリーフケース/Developer/Source/sdiff_2006-02-19_CMemFixed_3v.zip
                    無限ループ系バグが見つかったので, アップしなおしました;;
                    → ブリーフケース/Developer/Source/sdiff_2006-02-19_CMemFixed_3.1v.zip
                    原因は解らずじまいですけれど,
                    メッセージヘッダのデコード部分を強化すると収まったような, そうでないような.
                    無事を祈ります….
          • [4261] システムリソース不足時の例外処理の件 ラスティブ 2006年02月16日 19:45

            例外処理について検討中. 考えをまとめるついでにカキコ.

            try-catch ブロックを散らばらせずにメモリを確保しようと思うと,

            [3320] newの失敗の検出方法 by もか氏
            >調べた限りでは、
            >NULLに統一したくてもBCC551ではnothrowが効かないことがある。
            >VC6では operator delete( size_t, nothrow_t& ); が未宣言。
            >VC7xではnewヘッダをインクルードするかしないかで動作が変わる。
            >set_new_handler()を使う場合もstaticなオブジェクトが、
            >それより先にnewを実行するかもしれない。

            結局この問題にたどり着く.
            大域で new 演算子をオーバーロードするわけにも行かず,
            # 一部の標準ライブラリで不都合が起こると言う話を小耳に挟んだ.
            各クラスごとにわざわざ CMemory を使うのもかったるい,
            というか不適切な場合もあるかもしれない.
            では, こうしてみればどうか.

            ・標準 <vector> ライブラリで出来るところはそれでやる.
            ・文字列操作とかバッファリング操作とか, パフォーマンスが必要な場合は,
            string とか 自前の CMemory クラスとか, それなりのものを使う.

            で, 標準ライブラリでは new の失敗時に何かの例外を発行してくれることを祈りながら,
            その例外を上のほうのクラスで catch( ... ) ブロックで拾う... ( CProcess とか? )

            >SetUnhandledExceptionFilterで例外ハンドラを設定しておいて、
            >そこで無理矢理保存を行う

            ああ, そういえば既出でしたか... やっと意味がわかりました;;
            • [4283] Re:システムリソース不足時の例外処理の件 ラスティブ 2006年02月22日 19:56

              メモリ不足ネタ, 続きます.

              > [3320] newの失敗の検出方法 by もか氏
              > >調べた限りでは、
              > >NULLに統一したくてもBCC551ではnothrowが効かないことがある。
              > >VC6では operator delete( size_t, nothrow_t& ); が未宣言。
              > >VC7xではnewヘッダをインクルードするかしないかで動作が変わる。
              > >set_new_handler()を使う場合もstaticなオブジェクトが、
              > >それより先にnewを実行するかもしれない。
              >
              > 結局この問題にたどり着く.

              つまり, デフォルトの new 演算子を信用すべからずってコトだと気づく.

              > ・標準 <vector> ライブラリで出来るところはそれでやる.
              > ・文字列操作とかバッファリング操作とか, パフォーマンスが必要な場合は, string とか 自前の CMemory クラスとか, それなりのものを使う.
              >
              > で, 標準ライブラリでは new の失敗時に何かの例外を発行してくれることを祈りながら,
              > その例外を上のほうのクラスで catch( ... ) ブロックで拾う... ( CProcess とか? )

              しかし vector<T*> 型を T** 型として扱う部分にも対応できないといけない. そのためには CMem をあっさり取りやめて, CMemory の内装を vector<char> あたりで統一するか, CMem をテンプレート化して, template<> CMem<void*> 型を提供するかのどちらかが必要か…
              標準の型に縛られない自由さという点で後者が勝るけれど, 下手に作った道具よりも標準ライブラリの処理能力のほうが上という面では, 前者が勝る…

              > >SetUnhandledExceptionFilterで例外ハンドラを設定しておいて、
              > >そこで無理矢理保存を行う
              >
              > ああ, そういえば既出でしたか... やっと意味がわかりました;;

              例外を投げない可能性のある new を使った時点でアウトだから…
              CSakuraObjectBase(仮名) みたいなクラスに new, delete 一式をユーザー定義しておいて, そのクラスをすべてのクラスの基底とすれば処理系依存で悩むことはなくなりそうです.
              # 基底クラスの名付けで悩んでしまいます;;
              • [4287] Re2:システムリソース不足時の例外処理の件 ラスティブ 2006年02月23日 15:22

                > CSakuraObjectBase(仮名) みたいなクラスに new, delete 一式をユーザー定義しておいて, そのクラスをすべてのクラスの基底とすれば処理系依存で悩むことはなくなりそうです.
                差分ファイルをアップしました.

                Developer/Source/ sdiff_2006-02-19_CMemFixed_0v.zip
                ・CSakuraObject, CSakuraException の追加.
                ・CMemory の変更.
                追記:
                CEncoder の方はまだ組み込めてません. ごめんなさい.
              • [4288] Re2:システムリソース不足時の例外処理の件 ラスティブ 2006年02月24日 18:09

                > [3320] newの失敗の検出方法 by もか氏
                > >調べた限りでは、
                > >NULLに統一したくてもBCC551ではnothrowが効かないことがある。
                > >VC6では operator delete( size_t, nothrow_t& ); が未宣言。
                > >VC7xではnewヘッダをインクルードするかしないかで動作が変わる。
                > >set_new_handler()を使う場合もstaticなオブジェクトが、
                > >それより先にnewを実行するかもしれない。
                > >
                > > 結局この問題にたどり着く.
                >
                > つまり, デフォルトの new 演算子を信用すべからずってコトだと気づく.

                しかしこれは, 標準ライブラリを一切使わないと言ってるのと同じ ってコトに気づく.

                Developer/Source/ sdiff_2006-02-19_CMemFixed_1v.zip
                ・Microsoft のマニュアルに従って, Visual C++ の new 演算子を標準通りに正常に働かせるためのコードを追加.

                CSakuraObject クラスの役割がこの修正ですっかり薄れてしまったのですけど, 他に何か用途とかあればと思い, そのままにしてます.
                例外動作テストのために, Borland C++ 5.5.1 と Visual C++ 6.0 で実際に試したものを付けておきました.

                >NULLに統一したくてもBCC551ではnothrowが効かないことがある。

                これに関しては,
                #include <new>
                #Include <new.h>
                としておくと, こちらの環境では動いたので…
                放置してますごめんなさい.