dポイントプレゼントキャンペーン実施中!

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」番地からメモリを確保することは出来ないのでしょうか?

確保と開放が一対一に統合されていればこのような問題はない(常に同じアドレスを使用できるため)のですが、
アプリの使用上、仕方ないと考えております。

説明が複雑になってしまい、わかりにくいとは思いますが、
お詳しい方がおられましたら、ご教授の程宜しくお願い致します。

A 回答 (3件)

>このような場合、下記のように確保するヒープ領域の取得したアドレスが


>少しずつ増えてしまい、最終的には取得できなく(GlobalLockでNULLポインタ)なってしまいます。(4GB越え)

そんなはずはないと思います。マルチスレッドを使わない実験コードを書いて確かめてみてはどうでしょうか。
もちろん、単純に、確保、解放、確保、解放・・・とするのではなくて、

確保、確保、解放、確保、確保、解放、解放・・・・・
といった感じで。

あと、確保する単位が細かすぎるように思えます。もっと大きな単位で確保した場合は、どのような挙動になるでしょうか。
    • good
    • 0

★追記。


・スレッドが複数ある場合は絶対に排他処理をします。
 1つでも複数回呼ばれるなら排他処理すること。
 『一対一』となっているので排他処理が必要だね。
    • good
    • 0

★最も簡単な方法


>確保と開放が一対一に統合されていればこのような問題はない(常に同じアドレスを使用できるため)のですが、
>アプリの使用上、仕方ないと考えております。
 スレッドで確保、解放はしないでメインのスレッドで最大のサイズを確保。
 プログラム終了時などで解放すれば楽でしょう。
・あとスレッドで処理する場合は排他処理を行います。
 メモリ確保、解放だけでなく1つの変数の参照、代入でも排他処理を行うのが常識。
 次のリンクを読んでみましょう。
 http://itpro.nikkeibp.co.jp/article/COLUMN/20070 …→『第3回 マルチタスクに不可欠な同期の仕組みを学ぶ』

参考URL:http://itpro.nikkeibp.co.jp/article/COLUMN/20070 …
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!