Я использую std::map
с const std::string
ключами, и я подумал, что было бы неплохо не перемещать ключи по всему стеку, поэтому я изменил тип ключа на указатель:
class less_on_star : less<const string*> {
public:
virtual bool operator() (const string* left, const string *right);
};
less_on_star::operator() (const string* left, const string *right) {
return *left < *right;
}
class Foo {
private:
map<const string*, Bar*, less_on_star> bars;
}
Некоторое время он работал нормально, затем я начал получать ошибки сегментации, из-за которых строковый ключ терял свою натуру. Поле _M_p
указывало на NULL
или 0x2
, но ключи всегда были целы, когда я вставлял в карту:
bars[new string(on_stack_string)] = bar;
В gdb это выглядело так, как будто new string(on_stack_string)
указывало поле _M_p
на обычное расположение кучи, а не на значение стека. Есть ли что-то особенное в std::string
, что его нельзя использовать в подобных структурах данных? Может быть, я еще что-то тупил с ключами, но я не могу представить, что бы это могло быть.
std::string
внутренне использует выделенную кучу памяти для символьных данных. В g++sizeof(std::string)
равно 24. Поэтому, когда вы думали, что было бы неплохо не перемещать ключи по всему стеку, вы наверняка думали о чем-то другом. Что касается этой ошибки, она, вероятно, как-то связана с копированием g++ при записи. Бьюсь об заклад, строка без указателя покидает область действия и удаляет данные кучи, поскольку строка указателя используется только как временная и никогда не записывается. - person KitsuneYMG   schedule 09.03.2014