ページ 11

メモリの確保と開放について

Posted: 2012年1月23日(月) 09:33
by みけCAT
Windows Vista Home Premium SP2 32ビット、
Dev-C++ 4.9.9.2、gcc version 3.4.2 (mingw-special)です。

メモリの動的な確保と開放のタイミングについて質問があります。
ただし、メモリの確保と開放は以下のマクロで行うこととします。

コード:

/*マクロ*/
#define mymalloc(size) HeapAlloc(GetProcessHeap(),0,(size))
#define myfree(ptr) HeapFree(GetProcessHeap(),0,(ptr))

/*使用例*/
void* ptr=mymalloc(1000);/*メモリ確保*/
myfree(ptr);/*メモリ開放*/
この時、以下の処理のどれなら安全で、どれは危険でしょうか?
絶対安全だろうというものも含めてあります。
  1. 関数Aでメモリを確保し、同じ関数Aでメモリを開放
  2. 関数Aでメモリを確保し、同じソースコード内の関数Bでメモリを開放
  3. 関数Aでメモリを確保し、
    同じexeファイルにリンクする別のソースコード内の関数Bでメモリを開放
  4. 関数Aでメモリを確保し、
    同じスタティックリンクライブラリにリンクする別のソースコード内の関数Bでメモリを開放
  5. 関数Aでメモリを確保し、
    同じdllにリンクする別のソースコード内の関数Bでメモリを開放
  6. メインのexeファイルのソースコードの関数Aでメモリを確保し、
    それにリンクするスタティックリンクライブラリのソースコードの関数Bでメモリを開放
  7. リンクするスタティックリンクライブラリのソースコードの関数Aでメモリを確保し、
    メインのexeファイルのソースコードの関数Bでメモリを開放
  8. あるスタティックリンクライブラリのソースコードの関数Aでメモリを確保し、
    同じexeファイルにリンクする別のスタティックリンクライブラリのソースコードの関数Bでメモリを開放
  9. メインのdllのソースコードの関数Aでメモリを確保し、
    それにリンクするスタティックリンクライブラリのソースコードの関数Bでメモリを開放
  10. リンクするスタティックリンクライブラリのソースコードの関数Aでメモリを確保し、
    メインのdllのソースコードの関数Bでメモリを開放
  11. あるスタティックリンクライブラリのソースコードの関数Aでメモリを確保し、
    同じdllにリンクする別のスタティックリンクライブラリのソースコードの関数Bでメモリを開放
  12. メインのexeファイルのソースコードの関数Aでメモリを確保し、
    それが読みこむdllのソースコードの関数Bでメモリを開放
  13. あるdllのソースコードの関数Aでメモリを確保し、
    それを読み込むexeファイルのソースコードの関数Bでメモリを開放
  14. あるdllのソースコードの関数Aでメモリを確保し、
    同じexeファイルから読み込まれる別のdllのソースコードの関数Bでメモリを開放
  15. あるexeファイルにリンクされたスタティックリンクライブラリのソースコードの関数Aでメモリを確保し、
    そのexeファイルから読み込まれるdllのソースコードの関数Bでメモリを開放
  16. あるexeファイルから読み込まれるdllのソースコードの関数Aでメモリを確保し、
    そのexeファイルにリンクされたスタティックリンクライブラリのソースコードの関数Bでメモリを開放
少し多いですが、教えていただければありがたいです。
よろしくお願いします。

Re: メモリの確保と開放について

Posted: 2012年1月23日(月) 10:49
by beatle
言語はC++ということでよろしいですね?
関数Aとか関数Bとかの中身がわかりませんので安全か危険かは判断できません.
一つ言えるのは,確保したメモリを100%確実に,1回だけ解放する場合に「安全」といえる,ということです.

Re: メモリの確保と開放について

Posted: 2012年1月23日(月) 10:55
by YuO
使っているのが HeapAllocHeapFree なので,
  • ヒープメモリの確保と解放は kernel32.dll が担当する。故に,同一プロセス内であれば利用可能
  • メモリ空間はプロセスで分断されるため,他のプロセスからは当然ながら利用不可能
となります。

提示されている物は,全て同一プロセス内での話となりますので,全て問題なく動きます。
問題になるのはポインタをプロセス間通信で渡した状態で myfree した場合くらいですが,そもそもそのポインタは渡されたプロセスからは普通には使えないので,そういう状態にはまずならないでしょう。
# ReadProcessMemoryとか使えばデータにアクセスできますが……。

Re: メモリの確保と開放について

Posted: 2012年1月23日(月) 11:01
by みけCAT
beatle さんが書きました:言語はC++ということでよろしいですね?
言語はC言語です。
YuO さんが書きました:提示されている物は,全て同一プロセス内での話となりますので,全て問題なく動きます。
同一プロセスなら、別のスレッドでも大丈夫ということですか?

Re: メモリの確保と開放について

Posted: 2012年1月23日(月) 11:11
by softya(ソフト屋)
みけCAT さんが書きました:
beatle さんが書きました:言語はC++ということでよろしいですね?
言語はC言語です。
YuO さんが書きました:提示されている物は,全て同一プロセス内での話となりますので,全て問題なく動きます。
同一プロセスなら、別のスレッドでも大丈夫ということですか?
同一プロセス内ならスレッドが違っても解放できます。別プロセスは論理メモリ空間が違うので解放できません。
出来たとしてもアルゴリズム的に危険なので避けたほうが良いのは確かです。

あとdllとexeで使っているmsvcrt.dllとかが違うとmalloc/free系はやばいです。
HeapAllocはWin32APIなので大丈夫だとは思います。

Re: メモリの確保と開放について

Posted: 2012年1月23日(月) 11:19
by みけCAT
softya(ソフト屋) さんが書きました:同一プロセス内ならスレッドが違っても解放できます。別プロセスは論理メモリ空間が違うので解放できません。
出来たとしてもアルゴリズム的に危険なので避けたほうが良いのは確かです。

あとdllとexeで使っているmsvcrt.dllとかが違うとmalloc/free系はやばいです。
HeapAllocはWin32APIなので大丈夫だとは思います。
わかりました。ありがとうございます。