存储在地图中的赋值期间的字符串内存管理

时间:2009-07-20 16:37:38

标签: 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";

地图(在所有符合要求的平台上)是否仍然使用新值引用m_tmp

根据下面的虚拟程序,s的地址不会改变(linux AS4,gcc 3.4)。这方面的内存管理在整个平台上是否相同?

#include<string>
#include<iostream>

using namespace std;

int main()
{

   string s="Sasha";
   cout<<&s<<endl;  
   s="Bar";
   cout<<&s<<endl;  
   s="Foo";
   cout<<&s<<endl;  
}

3 个答案:

答案 0 :(得分:2)

为什么不这样做呢?

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

对我来说更安全。

答案 1 :(得分:1)

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

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

我认为这样的构造非常危险,我假设您希望密钥根据字符串而不是字符串的位置(即poitner值)来查找比较。

但是忽略了你对key的选择,你对m_tmp值的处理是安全且定义良好的(即改变一个将改变另一个,因为两者都是“相同”变量),提供“string 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使引用或迭代器无效)

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

答案 2 :(得分:0)

除非你受到类型限制,否则我建议将你的字符串包装在另一个类中,而不是做一个字符串&amp;直接地,会有一点点开销,但会给你一个彻底评论可变性原因的地方,同时也使代码在意义上更加明显。

Heck使它成为一个名为ReassignableString的类,如果你愿意,它的唯一成员是一个公共字符串。