Глюки с STL map
TProcessMap mymap;
при удалении элемента с помощью mymap.erase(key), где key - ключ, элемент не удаляется, при этом элемент mymap[key] возвращает 0 и it.find(key) также такого элемента не находит.
Но, элемент был добавлен, и при выводе всех элементов, он виден !!!! Вывожу вот так:
it=process_map.end();
if (it!=process_map.begin()) {
do {
it--;
printf("%d\n",(*it).second.first);
} while (it!=process_map.begin());
}
В чем могут быть грабли??
Есть у меня map:
TProcessMap mymap;
при удалении элемента с помощью mymap.erase(key), где key - ключ, элемент не удаляется, при этом элемент mymap[key] возвращает 0 и it.find(key) также такого элемента не находит.
Кв. скобки при отсутствии элемента должны вернуть дефолтовое значение для данного типа, т.е. для long - это 0, а для сложных типов - то что получится после вызова дефолтового конструктора.
If the argument key value is not found, then it is inserted along with the default value of the data type.
Но, элемент был добавлен, и при выводе всех элементов, он виден !!!! Вывожу вот так:
it=process_map.end();
if (it!=process_map.begin()) {
do {
it--;
printf("%d\n",(*it).second.first);
} while (it!=process_map.begin());
}
В чем могут быть грабли??
Можно проще. Тебе обязательно реверсивно выводить?
Тогда так:
it!=process_map.rend(); printf("%d\n",(*it++).second.first) );
Green прав, если в Вашем коде есть проверка наличия элемента путём вызова mymap[key], то это равносильно добавлению элемента с ключом key в таблицу. После этого он выводиться будет, без разницы - с начала или с конца таблицу просматривать.
Да у меня обратная проблема, элемент есть, а mymap[key] возвращает дефолтовое значние (то есть 0) и find() не находит, а при выводе, не зависимо от того прямой или обратный, элемент есть.
Да у меня обратная проблема, элемент есть, а mymap[key] возвращает дефолтовое значние (то есть 0) и find() не находит, а при выводе, не зависимо от того прямой или обратный, элемент есть.
Ага, та-а-ак, после удаления с помощью erase элемент остался, при переборе с помощью итератора до него цикл доходит, а вот mymap[key] даёт значение по умолчанию. Верно?
Попробуйте вместо long для ключа использовать string (временно, для проверки). Что скажет?
Ага, та-а-ак, после удаления с помощью erase элемент остался, при переборе с помощью итератора до него цикл доходит, а вот mymap[key] даёт значение по умолчанию. Верно?
Попробуйте вместо long для ключа использовать string (временно, для проверки). Что скажет?
Аналогично, не находится (не удаляется) примерно один на тысячу. Никакой зависимости между ключами не устанавливаются.
Ключ - это ID юникс процесса - от 1 до 99999.
Вот объявление:
time_t start;
unsigned long user_id;
unsigned long child_num;
} TProcessInfo;
typedef std::map<string,TProcessInfo> TProcessMap;
TProcessMap pmap;
Реализация:
void CProcessList::Add(long pid,unsigned long child_num) {
char tstr[16];sprintf(tstr,"%d",pid);
string spid(tstr);
TProcessMap::const_iterator it = pmap.find(spid);
if (it==pmap.end()) {
pmap[spid].child_num=child_num;
pmap[spid].user_id=0;
pmap[spid].start=time(NULL);
}
}
void CProcessList::Delete(long pid) {
char tstr[16];sprintf(tstr,"%d",pid);
string spid(tstr);
TProcessMap::const_iterator it = pmap.find(spid);
if (it!=pmap.end()) pmap.erase(spid);
}
void CProcessList::DumpInfo(char *str,int maxlength, int childsnum) {
char *pbuff=(char*)malloc(maxlength);
int i=0;
for( TProcessMap::iterator it=pmap.begin();it!
// Вывод
}
}
И еще вопрос. Чем отличается iterator от const_iterator ??
Аналогично, не находится (не удаляется) примерно один на тысячу. Никакой зависимости между ключами не устанавливаются.
Одна из вероятных причин - некорректная работа с памятью где-то еще.
Ключ - это ID юникс процесса - от 1 до 99999.
Вот объявление:
time_t start;
unsigned long user_id;
unsigned long child_num;
} TProcessInfo;
typedef std::map<string,TProcessInfo> TProcessMap;
TProcessMap pmap;
Реализация:
void CProcessList::Add(long pid,unsigned long child_num) {
char tstr[16];sprintf(tstr,"%d",pid);
string spid(tstr);
TProcessMap::const_iterator it = pmap.find(spid);
if (it==pmap.end()) {
pmap[spid].child_num=child_num;
pmap[spid].user_id=0;
pmap[spid].start=time(NULL);
}
}
Здесь четыре (вместо одного) раза выполняется поиск в map. Лучше использовать insert.
char tstr[16];sprintf(tstr,"%d",pid);
string spid(tstr);
TProcessMap::const_iterator it = pmap.find(spid);
if (it!=pmap.end()) pmap.erase(spid);
}
Здесь можно заменить const_iterator на iterator и через него удалять элемент: pmap.erase(it).
char *pbuff=(char*)malloc(maxlength);
А удаляешь случайно не через delete? Разве new char[maxlength] не проще написать?
for( TProcessMap::iterator it=pmap.begin();it!
// Вывод
}
}
И еще вопрос. Чем отличается iterator от const_iterator ??
const_iterator не дает менять элементы на которые он ссылается.
В VS 6.0 есть баги в реализации STL (какие именно сложно сказать).
Если на ней делаешь - попробуй собрать проект на VS 7.0, там вроде лучше реализован STL или найди STLport и его попробуй вместо стандартного.
Одна из вероятных причин - некорректная работа с памятью где-то еще.
Исключено. Дописываю менджер процессов к хорошо отлаженому и давно работающему серверу
Понял.
Понял.
free(), привычка.
Спасибо за советы. Может книжка есть какая??, лучше он-лайн, а то я с этим STL, как слепой котенок. Тыкаюсь в черные стенки.
Майк какой компилятор?
В VS 6.0 есть баги в реализации STL (какие именно сложно сказать).
Если на ней делаешь - попробуй собрать проект на VS 7.0, там вроде лучше реализован STL или найди STLport и его попробуй вместо стандартного.
gcc version 2.95.3 20010315 (release) [FreeBSD]
:P