2016-12-24 11 views
2

std :: setの中の要素へのポインタを格納することはできますか?例えばstd :: setの項目へのポインタを格納するのは安全ですか?

次危険例を取る...

std::vector<int> vec; 
//add a bunch of items 
int* ptr = &vec[10]; 
//add more items 
std::cout << *ptr << std::endl; 

この場合にポイントをptrをメモリは、それが再配置させるベクターに余分な要素を追加することによって無効化されたかもしれません。しかし、もし私がベクトルの代わりにリンクされたリストを使用していたのであれば、これはノードを再割り当てする必要がないので安全だと思います。

冗長文字列を扱うときにメモリを節約するためにstd :: setを使用します。次の例は安全でしょうか? std :: unordered_setではなくstd :: setであると思います。

const char* makeString(const char* s) 
{ 
    static std::set<std::string> strings_pool; 
    return strings_pool.insert(s).first->c_str(); 
} 

列cは、それが挿入されstrings_poolに存在しない場合、それ以外の場合は、プール内に既に文字列にイテレータを返します。どちらの場合でも、イテレータの値を取得し、ポインタを基になるcstringに返します。私はこれが安全な操作だと思っていますが、誰かがそれを確認することができます。

このリンクでは、http://en.cppreference.com/w/cpp/container/set/insertには「反復子または参照は無効です」と表示されています。私はこれが私がそれをすることができることを意味します。

std :: unordered_setのドキュメントの下に「参照は無効になっていません」と記載されています。つまり、std :: unordered_setも安全に使用できますか?

+0

'makeString'は私には見えます。 'std :: unordered_set'も同様に動作します。 –

+0

あなたが遭遇する可能性のある主な問題は、セット内の文字列が削除されると未解決のポインタです。コードが安全であることを確認したり、セットの要素を削除したりすることができないようにするために必要な追加の簿記をすべて取る準備ができていない限り、別のアプローチを探すことをお勧めします。 – andand

+0

@andandその追加の書物保管は(文脈によっては)些細なものかもしれません。 –

答えて

4

はい、setunordered_setの両方がこの点で安全です。参照が無効化されていない場合、ポインタも有効なままです。

ノードベースのコレクションが維持するのは簡単なプロパティです。 vectorとは異なり、メモリ内で値を移動する必要はありません。

関連する問題