найти с переменной char * не работает - PullRequest
0 голосов
/ 30 августа 2010

Я хотел бы знать, почему у меня ошибка памяти с этим:

Проблема появляется на char * value = aMap.find (keync) -> second

Если я поставлюmanualy char * value = "key0" это работает !!!

using std::map;
map <char*, char*> aMap;

void search(const char* key) {
    const int LEN = strlen(key);

    char* keync = new char[LEN];

    for (int i= 0; i < LEN; i++) {
       keync[i] = key[i];
    }

    char* value = aMap.find(keync)->second;

    printf("%s", value);

    delete[] keync;
}

int _tmain(int argc, _TCHAR* argv[])
{
    a["key0"] = "value0";
    search("key0");

    return 0;
}

Ответы [ 6 ]

2 голосов
/ 30 августа 2010

Вам необходимо добавить 1 к длине массива:

char* keync = new char[LEN+1];

Вы заканчиваете нулем за пределами выделенной строки.

(Кроме того, вы инициализируете aMap?)

1 голос
/ 30 августа 2010

Как отмечали другие, вам гораздо лучше использовать std::string для этого. Теперь, для реальной проблемы, почему вы не можете найти строку, потому что вы храните указатели на карте, т.е. ключом карты является переменная-указатель. Вы вставили char* в карту, но когда вы пытаетесь найти, вы снова делаете new. Это совершенно другой указатель (хотя строковое значение, которое они указывают, одинаково), следовательно, ваш поиск не удастся.

0 голосов
/ 30 августа 2010
using std::map;
map <char*, char*> aMap;

Прежде всего, эта карта будет сравнивать не строки (внутри поиска), а адреса. Поэтому в принципе вы ничего не найдете с помощью std :: map :: search, набрав строковые литералы.

void search(const char* key) {
    const int LEN = strlen(key);

    char* keync = new char[LEN];

    for (int i= 0; i < LEN; i++) {
       keync[i] = key[i];
    }

на данный момент у вас есть неопределенная строка, но это не имеет значения в вашем коде

    char* value = aMap.find(keync)->second;

здесь вы выполняете поиск, сравнивая значения (адреса) указателей, поэтому возвращаемый итератор карты недопустим (он равен aMap.end ()), поэтому либо имеет нулевой, либо нераспределенный указатель как second member

    printf("%s", value);

    delete[] keync;
}

int _tmain(int argc, _TCHAR* argv[])
{
    a["key0"] = "value0";
    search("key0");

    return 0;
}

Я надеюсь, это объясняет, почему вы должны использовать std :: string вместо char *

0 голосов
/ 30 августа 2010

Хорошо, ищите стартеры, вы должны бросить все символы * и использовать std::string, это, вероятно, сделает вашу проблему исчезнувшей.будет за концом выделенного массива

Копирование ключевого параметра неверно.Попробуйте это для размера:

using std::map;
map <char*, char*> aMap;

void search(const char* key) {
    const int LEN = strlen(key);

    char* keync = const_cast<char*>(key);

    char* value = aMap.find(keync)->second;

    printf("%s", value);
}

int main(int argc, char** argv)
{
    aMap["key0"] = "value0";
    search("key0");

    return 0;
}

Проблема, с которой вы столкнулись, заключается в том, что вы выделяли keync как strlen(key), что не учитывает нулевой терминатор.Затем в цикле копирования вы перезаписывали нулевой терминатор последним символом key.

Вся идея копирования входной строки неверна, и я заменил ее константным приведением в моем решении, так как это имеет больше смысла (насколько это возможно).

0 голосов
/ 30 августа 2010

Лучше использовать std :: string вместо char *. Еще одним плюсом использования std :: string является то, что вы избежите утечек памяти.

Другим решением будет предоставить карту с функцией сравнения, иначе они не будут сравнивать содержимое каждого символа *, а вместо этого указали адрес. Следующий пример был адаптирован из документации Sgi std :: map :

struct comp
{
  bool operator()(char* s1, char* s2) const
  {
    return strcmp(s1, s2) < 0;
  }
};

map<char*, char*, comp> stringMap;
0 голосов
/ 30 августа 2010

Одной из очевидных проблем является:

delete keync;

Поскольку вы использовали new [], оно должно быть:

delete[] keync;
...