LINUX.ORG.RU

std::map вопрос


0

0

нужна постоянная си строка на основе string (ссылаться на нее откудато), первое что пришло в голово:

string sss("test");
map<string, const char*> x;
x.insert(pair<string, const char*>(sss, sss.c_str()));


///где то в глубине

const map<string, const char*>::const_iterator mmm = x.find(sss);
if ( mmm!= x.end())
cout << mmm->second << std::endl;

безопасно?

либо надо в ручную копировать?:

char* x = new char[sss.sizeof()+1)];
x[sss.sizeof()+1)] = '\0';
strcpy(sss, sss.c_str());
x.insert(pair<string, const char*>(sss, x); ???

hello_world
() автор топика
Ответ на: комментарий от hello_world

Ни то ни другое. map<string, string>. A char* вынимать непосредственно в месте использования.

anonymous
()

Кто у тебя будет удалять память под строку? Используйю string чтоб не заморачиваться этим. Кстати вместо pair <....... >(...) использоваться надо make_pair код получается гибче (вдруг у тебя типы изменятся) и короче.

Reset ★★★★★
()
Ответ на: комментарий от hello_world

Так ссылайся на класс в котором строка лежит. Может полностью озвучишь задачу, а то мутно как-то звучит это всё.

Reset ★★★★★
()
Ответ на: комментарий от Reset

ну строка на которую можно сслылаться из других частей програамы допустим есть структура:

struct x{ /////// char* name; }

которую надо передать какойто функции, y (&x); ну собственно так то нельзя сделать x z; string sss("e3e") z.name = sss.c_str(); y(z);

hello_world
() автор топика
Ответ на: комментарий от hello_world

В Си++ принято делать так
struct X {
   std::string name_;
   
   X(const std::string name): name_(name) {}
};

В Си принято делать так:
struct X {
   char * name;
};

struct X * new_x(const char * n) {
    struct X * x = malloc(sizeof(struct X));
    x->name = strdup(n);
    return x;
}

void free_x(struct X * x) {
    free(x->name);
    free(x);
}


никаких глобальных мепов делать естественно не надо.

Reset ★★★★★
()
Ответ на: комментарий от hello_world

C++ чужды методы работы с памятью как в C. Если хочешь писать на C, забей на STL и используй glib.

По сабжу - в другие части программы должен приходить string. Не пытайся разбрасывать char*, а локализуй c_str() в пределах операторных скобок.

anonymous
()
Ответ на: комментарий от hello_world

> либо надо в ручную копировать?:

надо вручную копировать.

и перед тем как делать insert() надо проверять,
нет ли уже в map'е такой строки, и если есть,
возвращать её const char* -- а если же тупо делать
insert() то ранее созданный char[] будет затерт
и здравствуй утечка памяти.

алсо, ты изобретаешь http://en.wikipedia.org/wiki/String_intern_pool

anonymous
()
Ответ на: комментарий от anonymous

> и перед тем как делать insert() надо проверять, нет ли уже в map'е такой строки, и если есть, возвращать её const char* -- а если же тупо делать insert() то ранее созданный char[] будет затерт и здравствуй утечка памяти.

не надо этого делать, в insert из std::map это всё уже есть, читайте доки

Reset ★★★★★
()
Ответ на: комментарий от Reset

> это всё уже есть

что "это"?

я говорю что если строки совпадают, то заново генерить char[] нет смысла. к инсерту в стд мап это никакого отношения не имеет

anonymous
()
Ответ на: комментарий от anonymous

ничего не будет затерта, она просто не вставится и будет возврашен pair, с итератором указывающим на ранее вставленную и false

hello_world
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.