- 締切済み
GlobalAlloc について
GlobalAlloc について 質問させて下さい。 VC++ 2005 MFC で開発しております。 仕様の概要と致しまして、 ::GlobalAlloc()でHGLOBALを取得し、 メンバ変数に格納(Arrayでリサイクルしていくイメージ)した後、スレッドを走らせ格納したHGLOBALを 使い処理をした後に、GlobalFree()でメモリを開放します。 アプリの仕様上、スレッドの処理に少々時間がかかり GlobalAlloc()とGlobalFree()が必ずしも一対一で実行されず、 スレッドのGlobalFree()が実行される前に別のGlobalAlloc()がくることがあります。 このような場合、下記のように確保するヒープ領域の取得したアドレスが 少しずつ増えてしまい、最終的には取得できなく(GlobalLockでNULLポインタ)なってしまいます。(4GB越え) 8バイトずつアドレスが増えていくとして ------------------------------------------------- ・一対一の場合 (同じアドレスが使用できる) 確保 開放 (1)0008 (2)0008 (3)0008 (4)0008 (5)0008 ・一対一でない場合 (開放される前に確保するので新しいアドレスを使用してしまう) 確保 開放 (1)0008 (2)0008 (3)0008 (4)0016 (5)0008((3)メモリ) (6)0024 (7)0032 (8)0040 (9)0016((4)メモリ) (10)0024((6)メモリ) (11)0032((7)メモリ) (12)0048 : : : ------------------------------------------------- GlobalFree()がもれているのではなく メモリを確保したものは遅れはするものの必ず開放はしています。 このような場合、上記の「一対一でない場合」の (6)で「0024」番地ではなく「0008」番地からメモリを確保することは出来ないのでしょうか? 確保と開放が一対一に統合されていればこのような問題はない(常に同じアドレスを使用できるため)のですが、 アプリの使用上、仕方ないと考えております。 説明が複雑になってしまい、わかりにくいとは思いますが、 お詳しい方がおられましたら、ご教授の程宜しくお願い致します。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- titokani
- ベストアンサー率19% (341/1726)
>このような場合、下記のように確保するヒープ領域の取得したアドレスが >少しずつ増えてしまい、最終的には取得できなく(GlobalLockでNULLポインタ)なってしまいます。(4GB越え) そんなはずはないと思います。マルチスレッドを使わない実験コードを書いて確かめてみてはどうでしょうか。 もちろん、単純に、確保、解放、確保、解放・・・とするのではなくて、 確保、確保、解放、確保、確保、解放、解放・・・・・ といった感じで。 あと、確保する単位が細かすぎるように思えます。もっと大きな単位で確保した場合は、どのような挙動になるでしょうか。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★追記。 ・スレッドが複数ある場合は絶対に排他処理をします。 1つでも複数回呼ばれるなら排他処理すること。 『一対一』となっているので排他処理が必要だね。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★最も簡単な方法 >確保と開放が一対一に統合されていればこのような問題はない(常に同じアドレスを使用できるため)のですが、 >アプリの使用上、仕方ないと考えております。 スレッドで確保、解放はしないでメインのスレッドで最大のサイズを確保。 プログラム終了時などで解放すれば楽でしょう。 ・あとスレッドで処理する場合は排他処理を行います。 メモリ確保、解放だけでなく1つの変数の参照、代入でも排他処理を行うのが常識。 次のリンクを読んでみましょう。 http://itpro.nikkeibp.co.jp/article/COLUMN/20070603/273403/→『第3回 マルチタスクに不可欠な同期の仕組みを学ぶ』