- 締切済み
GUIアプリケーションで連続領域がとれません。
WinXP上でVC6.1SP6を使用しGUIアプリケーションを作成しています。 WinMainの直下で下記を実行してもNULLが戻ります。 char *p; p=malloc(0x65000000); ちなみにConsoleアプリの場合main直下で同じ処理が正常に動作します。 2分探索で確保出来る領域を調べるとGUIアプリの場合、mallocで確保されるフリーアドレス空間が分断されているように思われます。 WinMain直下での現象ですので、OSのバッグとしか考えられないのですが、なにか回避法はないものでしょうか? W2kでも最大空きブロックのサイズは違いますが、同じ現象が確認できました。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- terra5
- ベストアンサー率34% (574/1662)
ConsoleとWindowsアプリではスタートアップも違うでしょうから、十分ありえると思いますが。 リンクしているライブラリも違えば、プログラムサイズも違うでしょうし、ヒープ領域サイズ、スタックサイズ等もどうなっているかわかりませんし。 あと、DLLの動きもからんでくるでしょう。 APIもGUIに限りませんし。 原因をはっきりさせたいなら、やはり最低でもスタートアップの処理を追うしかないでしょうし、 上記の内容もチェックする必要があると思います。 多分、全部は追いきれないと思いますが。 普通はOSが何であるかにかかわらずそんな大きな連続領域を必要とするようなプログラムが問題として対応すると思いますが。 実際動作しないわけですから。 逆にどうしても必要なら、はじめからそれ相応の対処、準備、環境の選択を行うべきでしょうし。
- sha-girl
- ベストアンサー率52% (430/816)
>知りたいのは、この現象はWinプログラマーの皆さんには一般的に知れ渡っている物なのかと言うことなんです。 ANSIでは mallocで確保できない場合はNULL、0、あるいはそれを表すポインタが返ってくるとになっています。 普通のプログラマは知っているでしょう。mallocの説明をみればそう記述してあるはずです。 メモリの断片化がおきるのはGUI関連かどうかは関係ありません。 linuxだろうがMacOSだろうが長時間使えばメモリは断片化します。 APIのHeapAllocを使ってみてください。 恐らくSTATUS_NO_MEMORYのエラーが返ると思います。 Windowsの場合mallocも結局は内部でAPIのHeapAllocを呼んでいます。 0x65000000が尋常ではない値なのです。 そもそもWin2000ProではOS自体4Gバイト以上のメモリを扱えないですし、 その1/3の値を連続領域でとろうとしても普通は確保できないでしょう。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
リリースモードでビルドしてもですか? あと自分でスタートアップルーチンを自分で見てみてはいかがでしょうか? VC6++でしたらCRT0.Cです。ソースついてるんですから疑う前に確認しましょう。 あとは、それでも上手くいかないようでしたらスタートアップルーチン自分で空のを書いちゃえばいいかと。ランタイム関数は使えなくなるんでメモリ確保はHeapAlloc()とかになりますが。
- terra5
- ベストアンサー率34% (574/1662)
GUIを使うと細かいメモリアロケートと開放が大分発生すると思いますので、 分断化はしかたない現象と思いますが。 それより連続領域で約1.6GByteもとるプログラムをなんとかすべきでしょう。 データ構造とかメモリ確保の方法とかアルゴリズムに問題があるのでは? まともに動かすには物理メモリどれぐらい必要でしょうね。 どうしてもというのであれば、Consoleだと取れるということなら、 処理はconsoleのプロセスで行い、インターフェイス部だけWinMainにもっていていって、なんらかのプロセス間通信で処理することになると思いますが。
補足
terra5様、質問にご回答いただきありがとうございます。 どうも言葉が足りなかった様で申し訳ありません。 知りたいのは、この現象はWinプログラマーの皆さんには一般的に知れ渡っている物なのかと言うことなんです。 1.6Gというのは、検証用として記載したもので、実際のプログラムではご指摘の様な方法で対処は可能かと思います。 ただそのために、開発のコストがかさむので、この現象が既知で有ることを示す必要があり、質問をさせていただいた次第です。 一点気になるのですが、ご指摘の「細分化が発生する」のはGUI関連のAPIを使用していく過程での事ではないですか? その現象であれば理解できるのですが問題は、WinMain直後(直下では無いですね)で起きています。 テスト作業はVCで新規にWin32Applicationを選び「標準的なHelloWorldアプリケーション」を作成して下記の様に3行追加しただけです。 ----- from here --------- int APIENTRY WinMain(HINSTANCE hInstance,... { MSG msg; HACCEL hAccelTable; char *p; p=(char *)malloc(0x65000000); if(p==NULL) exit(1); ------ to here ------ つまり何も処理を行っていない時点での話しですの、crt0.objの中で行われているであろう初期化処理を疑っている訳です。 仰っている細分化が、この現象のことで有れば万々歳なのですが、どうなのでしょうか。
お礼
たびたびのレスをいただき恐縮です。 結局MSのサポートを受けて問題は解決いたしました。 ありがとうございました。