C++ 分配期间存储在映射中的字符串内存管理

C++ 分配期间存储在映射中的字符串内存管理,c++,stl,C++,Stl,我有一个字符串,我想把这个字符串的引用放到一个映射中 string m_tmp; map<pair<string, string>, string&> m; m[pair<string, string>("Foo","Bar")]= m_tmp; then, I change the m_tmp; m_tmp="DFDFD"; 虽然s的地址没有改变(在c++中不允许变量改变),但是字符串的内容可能会改变(例如s.c_str()中的指针),所以在处理

我有一个字符串,我想把这个字符串的引用放到一个映射中

string m_tmp;
map<pair<string, string>, string&> m;
m[pair<string, string>("Foo","Bar")]= m_tmp;

then, I change the m_tmp;
m_tmp="DFDFD";

虽然s的地址没有改变(在c++中不允许变量改变),但是字符串的内容可能会改变(例如s.c_str()中的指针),所以在处理类似的东西时要小心

map<pair<const char*, const char*>, string&> m;
map-m;

id考虑这样一个非常危险的结构,例如,假设您希望密钥基于字符串而不是字符串的位置(即POITER值)寻找比较。 但是,忽略您对键的选择,您对m_tmp值所做的操作是安全且定义良好的(即更改一个会更改另一个,因为这两个变量都是“相同”的),前提是“字符串m_tmp;”不超出范围(或以其他方式删除),然后您尝试通过映射访问它(因为它不再引用有效内存)

以下是不安全的

std::map<int, string &> myMap;
void foo()
{
    string s = "Hello World";
    myMap[5] = s;
}
int main()
{
    foo();
    //string s was destroyed when foo() returned, so myMap[5] is no longer a valid reference,
    //so it is not defined what will happen here, hopefully an access violation
    //rather than some obscure bug because the stack/heap got corrupted
    std::cout << myMap[5] << std::end;
}
std::map myMap;
void foo()
{
字符串s=“Hello World”;
myMap[5]=s;
}
int main()
{
foo();
//返回foo()时字符串s已被销毁,因此myMap[5]不再是有效的引用,
//所以这里没有定义会发生什么,希望是访问冲突
//而不是因为堆栈/堆损坏而出现一些模糊的错误

std::cout为什么不改为这样做:

map<pair<string, string>, shared_ptr<string> > m;
map-m;

对我来说似乎更安全。

除非您的类型受到限制,否则我建议您将字符串包装到另一个类中,而不是直接使用字符串&这样会有一点开销,但会给您提供一个位置,让您彻底注释易变性的原因,同时也让代码的含义更加明显


如果您愿意,请将其设置为一个名为ReassignableString的类,其唯一成员为公共字符串。

好的,问题不在于字符串,而在于前者。对于前者,我可以更改为这一对…实际上,我将根据您的建议在我的情况下,字符串不会被销毁,因为我引用了实例的成员。那么,正如我所说的,它是安全的,更改其中一个将更改另一个:)这会起作用吗?顺便说一句:map m;m[pair(“Foo”,“Bar”)“string”]?我刚刚注意到:为什么共享\u ptr.看起来像是对meshared\u ptr的过度杀伤力。它会将对象的副本数减少到一个。这取决于您的用例,但可能不是必需的。访问速度也会更快,因为您只需移动指针,而不是字符串对象(带有底层链的副本)。如果您的字符串很短,这可能有点过头了。您使用的是对字符串的引用,因此假设您正在优化内存性能。95%的时间映射是可以使用的,但是,您是正确的。我使用引用是为了确保在引用更改时更新映射…而不必更新映射表达式合法地。。。
std::map<int,string> myMap;
myMap[5] = "x";
string &s = myMap[5];//get a referecnce
myMap[5] = "Foo";
std::cout << s << std::end;//print Foo
s = "Bar";
std::cout << myMap[5] << std::endl;//print Bar
map<pair<string, string>, shared_ptr<string> > m;