2012-04-05 1 views
4

Я использую карту C++ для реализации словаря в моей программе. Моя функция получает структуру как аргумент и должна возвращать связанное значение на основе элемента structure.name, который является char named[32]. Следующий код демонстрирует мою проблему:C++ map :: find char * vs. char []

map <const char *, const char *> myMap; 
myMap.insert(pair<const char *, const char *>("test", "myTest")); 

char *p = "test"; 
char buf[5] = {'\0'}; 
strcpy(buf, "test"); 

cout << myMap.find(p)->second << endl; // WORKS 
cout << myMap.find("test")->second << endl; // WORKS 
cout << myMap.find(buf)->second << endl; // DOES NOT WORK 

Я не знаю, почему третий случай не работает, и что я должен сделать, чтобы заставить его работать. Я отлаживал приведенный выше код, чтобы посмотреть переданные значения, и я все еще не могу понять проблему.

Спасибо!

ответ

8

Сравнение указателей, а не сравнение строк, будет выполнено с помощью map для поиска элементов. Первые две работают потому, что "test" является строковым литералом и будет иметь тот же адрес. Последнее не работает, потому что buf не будет иметь тот же адрес, что и "test".

Чтобы исправить это, используйте std::string или определите компаратор для char*.

+2

На самом деле, это реализация, определяемая тем, имеют ли два строковых литерала с одинаковыми символами один и тот же адрес. Поэтому '' test "==" test "' может быть ложным. Кроме того, строковые литералы могут перекрываться, поэтому «путаница» + 3 == «слияние» может быть правдой. –

5

Ключ карты - это указатель, а не значение. Все ваши литературные «тестовые» строки разделяют память, потому что компилятор умен таким образом, поэтому их указатели одинаковы, но buf - это другой адрес памяти.

Вам необходимо использовать ключ карты с семантикой равенства значений, например std::string, вместо char*.

1

Как уже упоминалось, вы сравниваете адрес не по значению. Я хотел, чтобы связать эту статью:

Is a string literal in c++ created in static memory?

Поскольку все литералы имели один и тот же адрес, это объясняет, почему ваше сравнение строковых литералов работало, даже если базовый тип еще const char * (но в зависимости от компилятора это может не ВСЕГДА это так)

0

Его так как buf [5] выделяет память, обозначенную buf, но когда u использует указатель «p», он указывает на ту же ячейку памяти, что и карта. Поэтому всегда используйте std :: string в ключе вместо переменной указателя.

 Смежные вопросы

  • Нет связанных вопросов^_^