2016-11-29 2 views
0

ヒープ上でstd :: unordered_mapを宣言し、いくつかの操作を実行してから解放する構文は何ですか?私がやっている:ヒープで宣言されたstd :: unordered_map <int32_t、int32_t>

std::unordered_map<int32_t, int32_t> *map_temp_last_close = new std::unordered_map<int32_t, int32_t>; 
*(map_temp_last_close[val]) = *(int32_t*)(read_buffer + 30); //this happens multiple times in a loop 
int32_t some_val = val * (*(map_temp_last_close[val])) 
map_temp_last_close->clear(); 
delete(map_temp_last_close); 

EDIT: を私はヒープ上にそれを持っている必要がありますなぜ?私はいつもネットワークからデータを絶え間なく受信する常時稼動の機能を持っており、場合によってはデータをマップに保存して処理します。マップの使用が終了すると、再び私のプロトコルでそのメッセージを受け取ることはないので、マップは必要ではないが、関数は無限ループ上にあるので範囲外ではないことを知っているネットワークからの読み取り)。だから私はfreeまたはdeleteまたは何かを呼び出すことによって、そのメモリを解放したいと思います。

+3

なぜこれをヒープで行う必要がありますか?なぜスタックしていないのですか? –

+0

@SergeRoussak編集を参照してください。 – user2635088

+2

@ user2635088:ローカルスタック変数(正式には、自動保存期間を持つローカル)は、囲みスコープの終わりで破棄されます。これは関数よりも小さくなります。関数内にスコープを作成するには、 '{}'を使用します。または、すでに行っているように 'map'で' clear() 'を呼び出すだけです。これは重要なリソースを回復します(' sizeof(unordered_map) ')は無視してもかまいません。心配する必要があり、 'clear()'がそれを処理する必要があります)。 –

答えて

2

エラーは中括弧の位置付けでした。 を最初に参照解除し、次にをデータ構造体に挿入する必要があります。

std::unordered_mapはすでにヒープにデータを内部的に保存しているので、最初のヒープには入れませんが、本当に必要な場合は、私が考えることができる最も簡単で安全な方法は次のとおりです。

auto map_temp_last_close = std::make_unique<std::unordered_map<int32_t, int32_t>>() 
(*map_temp_last_close)[val] = *(int32_t*)(read_buffer + 30); 
int32_t some_val = val * (*map_temp_last_close)[val]; 

//map object will get destroyed automatically when map_temp_last_close goes out of scope, but if you want to delete it earlier, you can use: 
map_temp_last_close.reset(); 

これは、ヒープ上std::unordered_mapし、それを管理してローカルunique_ptr変数を作成:map_temp_last_closeがスコープの外に出るときはいつでも、それはが自動的に削除されます(リターン、例外または現在のスコープが終了するというだけの理由経由であることを)地図。また、マップは自動的にそれを行うので、破壊の前にclearに電話する理由はありません。

注:
この式(read_bufferの種類に応じて)ほとんどの場合:*(int32_t*)(read_buffer + 30)は未定義の動作です。

+0

ありがとうございます。だから 'read_buffer'は、' recv'を呼び出すとネットワークからバイトを受け取ったときに埋め込まれたchar配列です。ネットワークプロトコルが、その位置にint32_tがあることを指示する場合、これはまだ未定義の動作ですか?私が知っている 'int32_t'値が特定の範囲外にある場合、プロトコルにエラーがあり、それに応じてその動作を処理できます。 – user2635088

+0

@ user2635088:はい、それは2つの方法で動作が定義されていません。 2番目はアライメントの違反です( '30'は' sizeof(int32_t) 'の倍数ではありません)。代わりに 'memcpy(&some_val、read_buffer + 30、4)'を使って値を取得してください。ミスアライメントを許容するプラットフォームを使用している場合、コンパイラはすべてのビットをオリジナルと同じくらい効率的に32ビット移動を生成しますが、その動作は正式に定義されています。配置が重要なプラットフォームでは、作業コードを取得します。 –

+0

@BenVoigt(* map_temp_last_close)[val]にコピーするのに 'memcpy'を使うことができますか?それは 'memcpy(&((* map_temp_last_close)[val])、read_buffer + 30、4)でしょうか? – user2635088

関連する問題