Namaran

Code daily. Without assist.

2026-09-14

key_ptrs.cpp

#include <map>
#include <string>
#include <vector>

std::vector<const std::string*> key_ptrs(const std::map<std::string, int>& m) {
    std::vector<const std::string*> out;
    for (const std::pair<std::string, int>& kv : m)
        out.push_back(&kv.first);
    return out;
}

mの各キーへのポインタを集める関数です。コンパイルは通りますが、返ってきたポインタを読むとゴミが出たりクラッシュしたりします。何が問題で、どう直せばよいでしょうか?

Answer

std::map<std::string, int>の要素型はstd::pair<const std::string, int>で、ループ変数のstd::pair<std::string, int>とはキーのconstの有無だけ違う、別の型です。const参照は変換で作られた一時オブジェクトにも束縛できるため、反復のたびに要素のコピーが作られ、kvはそのコピーを指します。コピーはその反復の終わりで破棄されるので、集めたポインタはすべてダングリングです。要素型をそのまま受ければ直ります:

for (const auto& kv : m)
    out.push_back(&kv.first);