:スレッド終了時にスレッドローカルヒープメモリが解放されないのはなぜですか?少し大きすぎるだろう完全な例を掲載、この構造を参照すると、
__thread char* buf;
buf = malloc(1000);
Valgrindのは、バイトが「間違い」失われていると言います。彼らは単に「まだ到達可能」ではありませんか?
:スレッド終了時にスレッドローカルヒープメモリが解放されないのはなぜですか?少し大きすぎるだろう完全な例を掲載、この構造を参照すると、
__thread char* buf;
buf = malloc(1000);
Valgrindのは、バイトが「間違い」失われていると言います。彼らは単に「まだ到達可能」ではありませんか?
割り当てられたメモリがスレッドローカルではないためです。それはすべてのスレッドによって共有されています。
変数はスレッドローカルなので、スコープ外になると割り当てられたメモリは確実に失われます(そのポインタが他の場所にコピーされていないと、明らかにvalgrindが確実にレポートするためではありません)。紛失)
あなたはfree
にする必要があります。
free
を呼び出して明示的に割り当てを解除する必要があります。
malloc
によって割り当てられたヒープ割り当てメモリは、free
を呼び出すことによって明示的に解放されるまで再要求されません。スレッドが終了すると、割り当てられたローカル記憶域オブジェクトのみが自動的に割り当てが解除されます。
スレッドが終了すると割り当てられたメモリへのポインタがないため、これは間違いなく失われます。メモリを指すポインタはスレッドのスタックに対してローカルであり、スレッドが終了すると破棄されますが、割り当てられたメモリはヒープメモリであり、割り当て解除されません。
ブロックへの唯一のポインタがスレッドローカルの場合、スレッドを終了すると、唯一のポインタが失われてしまいます。
これは、もはや到達可能ではなく=間違いなく失われたことを意味します。
他の人が言っているように、あなたはfree
です。
これは、すべてのスレッドが共通のヒープを共有し、概念的にはメモリの所有権をスレッド間で渡すことができるという理由があります。 1つのスレッドは何かをmallocし、別のスレッドはそれを解放することができます。しかし、ヒープはメモリを誰が所有しているのか分からないので、スレッドが終了すると(たとえヒープがどのスレッドをmallocしたとしても)安全に削除できませんでした。
プロセスが終了すると、すべてのヒープメモリが効果的に解放されますが、個別には実行されません。プロセスのヒープ全体(おそらく1つの大きな塊)がオペレーティングシステムに返されます。
スレッド記憶域の場合、メモリは他のスレッドと共有されていないため、スレッドは安全に削除することができます。 (少なくとも論理的には共有されていませんが、他のスレッドが偶然メモリにアクセスすることはありません。例えば、配列のオーバーフローの方法によって) – Blub
@Blub:*ポインタ*のみがスレッドローカルです。それが実際に指していることはありません。 'malloc'は、スレッドローカルポインタにリターンを割り当てることを知る方法がありません。 – Roddy
@Blub:一般に、メモリが他のスレッドからアクセスできないと判断することは、停止問題と同じです。だからあなたが提案しているのは、一時停止問題の特別なケースがあなたのコンパイラによって解決できるかどうかに基づいて、メモリが解放されることがあり、時には解放されないということです。 double-freeは非常に危険な未定義の動作を引き起こし、自動的に解放されるかどうかを知る方法がないことを考慮すると、これは災害のレシピのように聞こえます! –
これは、「味が良い」/「少ない充填」のようなものです。 Valgrindは正しいですし、データは "まだ到達可能です"。たとえば、データにパスワードが含まれている場合、100%はヒープスキャンからそれらを抽出できます。一意の乱数でデータが開始された場合は、それを再配置することができます。 Valgrindは、ポインタを介してデータにアクセスできなくなったことを意味します。
Uhmはい、スレッドローカルです。それが__threadの全体のポイントです。 – Blub
いいえ、変数だけが..そして誰がこれを下降させましたか? –
それは正しい答えです。落下者は愚かではありません。 –