コメントからの引用:
正しい方法は、別のを追加することです 構造体へのメンバー:解放関数へのポインター。
静的割り当てと動的割り当てだけではありません。 いくつかあります malloc()
のうち可能なアロケーター
Unix ライクなシステムでは、次のようになります:
- 静的変数
- スタック上
- スタック上ですが、動的に割り当てられます (つまり、
alloca()
) malloc()
で割り当てられたヒープ上new
で割り当てられたヒープ上- ヒープ上、
new[]
で割り当てられた配列の途中 - ヒープ上、
malloc()
で割り当てられた構造体内 - ヒープ上、
new
で割り当てられたオブジェクトの基本クラス内 mmap
で割り当て- カスタム アロケータで割り当て
- 上記のいくつかの組み合わせやバリエーションを含む、さらに多くのオプション
Windows では、いくつかのランタイム LocalAlloc
もあります。 、 GlobalAlloc
、 HeapAlloc
(簡単に作成できるいくつかのヒープを使用) など。
使用したアロケータの正しい解放関数を使用して、常にメモリを解放する必要があります。したがって、メモリの割り当てを担当するプログラムの部分もメモリを解放する必要があります。または、メモリを解放するコードに正しい解放関数 (またはその周りのラッパー) を渡す必要があります。
また、ポインターが常に特定のアロケーターで割り当てられるように要求するか、アロケーターを自分で提供することで、問題全体を回避することもできます (メモリを割り当てる関数と、場合によってはメモリを解放する関数の形式で)。アロケータを自分で提供する場合は、トリック (タグ付きポインタなど) を使用して、静的割り当ても使用できるようにすることもできます (ただし、このアプローチの詳細についてはここでは説明しません)。
Raymond Chen のブログ投稿 (Windows 中心ですが、概念はどこでも同じです):モジュール境界を越えたメモリの割り当てと解放
ACE ライブラリは、あらゆる場所でこれを行います。彼らがどのようにそれを行うかを確認できるかもしれません。一般的には、最初からこれを行う必要はないでしょう...
ヒープ、スタック、および静的データ領域は一般にメモリの異なる範囲を占有するため、プロセス メモリ マップの詳細な知識があれば、アドレスを見て、それがどの割り当て領域にあるかを判断することができます。およびコンパイラ固有であるため、コードの移植がより困難になります。