Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Глюки с STL map

4
26 марта 2004 года
mike
3.7K / / 01.10.2002
Есть у меня map:

 
Код:
typedef std::map<long,long> TProcessMap;

TProcessMap mymap;


при удалении элемента с помощью mymap.erase(key), где key - ключ, элемент не удаляется, при этом элемент mymap[key] возвращает 0 и it.find(key) также такого элемента не находит.

Но, элемент был добавлен, и при выводе всех элементов, он виден !!!! Вывожу вот так:

 
Код:
TProcessMap::iterator it;
    it=process_map.end();
    if (it!=process_map.begin()) {
        do {
            it--;
            printf("%d\n",(*it).second.first);
            } while (it!=process_map.begin());
        }


В чем могут быть грабли??
3
26 марта 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by mike
Есть у меня map:

 
Код:
typedef std::map<long,long> TProcessMap;

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.


Цитата:
Originally posted by mike
Но, элемент был добавлен, и при выводе всех элементов, он виден !!!! Вывожу вот так:

 
Код:
TProcessMap::iterator it;
    it=process_map.end();
    if (it!=process_map.begin()) {
        do {
            it--;
            printf("%d\n",(*it).second.first);
            } while (it!=process_map.begin());
        }


В чем могут быть грабли??



Можно проще. Тебе обязательно реверсивно выводить?
Тогда так:

 
Код:
for( TProcessMap::iterator it=process_map.rbegin();
it!=process_map.rend(); printf("%d\n",(*it++).second.first) );
310
27 марта 2004 года
fellow
853 / / 17.03.2003
Green прав, если в Вашем коде есть проверка наличия элемента путём вызова mymap[key], то это равносильно добавлению элемента с ключом key в таблицу. После этого он выводиться будет, без разницы - с начала или с конца таблицу просматривать.
4
27 марта 2004 года
mike
3.7K / / 01.10.2002
Цитата:
Originally posted by fellow
Green прав, если в Вашем коде есть проверка наличия элемента путём вызова mymap[key], то это равносильно добавлению элемента с ключом key в таблицу. После этого он выводиться будет, без разницы - с начала или с конца таблицу просматривать.



Да у меня обратная проблема, элемент есть, а mymap[key] возвращает дефолтовое значние (то есть 0) и find() не находит, а при выводе, не зависимо от того прямой или обратный, элемент есть.

310
27 марта 2004 года
fellow
853 / / 17.03.2003
Цитата:
Originally posted by mike


Да у меня обратная проблема, элемент есть, а mymap[key] возвращает дефолтовое значние (то есть 0) и find() не находит, а при выводе, не зависимо от того прямой или обратный, элемент есть.


Ага, та-а-ак, после удаления с помощью erase элемент остался, при переборе с помощью итератора до него цикл доходит, а вот mymap[key] даёт значение по умолчанию. Верно?

Попробуйте вместо long для ключа использовать string (временно, для проверки). Что скажет?

4
30 марта 2004 года
mike
3.7K / / 01.10.2002
Цитата:
Originally posted by fellow

Ага, та-а-ак, после удаления с помощью erase элемент остался, при переборе с помощью итератора до него цикл доходит, а вот mymap[key] даёт значение по умолчанию. Верно?

Попробуйте вместо long для ключа использовать string (временно, для проверки). Что скажет?



Аналогично, не находится (не удаляется) примерно один на тысячу. Никакой зависимости между ключами не устанавливаются.

Ключ - это ID юникс процесса - от 1 до 99999.

Вот объявление:

 
Код:
typedef struct {
    time_t start;
    unsigned long user_id;
    unsigned long child_num;
    } TProcessInfo;

typedef std::map<string,TProcessInfo> TProcessMap;

TProcessMap pmap;


Реализация:

Код:
// Add one element to process list  
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 ??
7.3K
30 марта 2004 года
Alchemist
1 / / 30.03.2004
Цитата:
Originally posted by mike


Аналогично, не находится (не удаляется) примерно один на тысячу. Никакой зависимости между ключами не устанавливаются.



Одна из вероятных причин - некорректная работа с памятью где-то еще.

Цитата:


Ключ - это ID юникс процесса - от 1 до 99999.

Вот объявление:

 
Код:
typedef struct {
    time_t start;
    unsigned long user_id;
    unsigned long child_num;
    } TProcessInfo;

typedef std::map<string,TProcessInfo> TProcessMap;

TProcessMap pmap;


Реализация:

Код:
// Add one element to process list  
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.

Цитата:
 
Код:
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);
    }



Здесь можно заменить const_iterator на iterator и через него удалять элемент: pmap.erase(it).

Цитата:
 
Код:
void CProcessList::DumpInfo(char *str,int maxlength, int childsnum) {
    char *pbuff=(char*)malloc(maxlength);



А удаляешь случайно не через delete? Разве new char[maxlength] не проще написать?

Цитата:
 
Код:
int i=0;
    for( TProcessMap::iterator it=pmap.begin();it!
// Вывод
        }
    }


И еще вопрос. Чем отличается iterator от const_iterator ??



const_iterator не дает менять элементы на которые он ссылается.

475
30 марта 2004 года
Winnie
90 / / 20.03.2000
Майк какой компилятор?
В VS 6.0 есть баги в реализации STL (какие именно сложно сказать).
Если на ней делаешь - попробуй собрать проект на VS 7.0, там вроде лучше реализован STL или найди STLport и его попробуй вместо стандартного.
4
30 марта 2004 года
mike
3.7K / / 01.10.2002
Цитата:
Originally posted by Alchemist
Одна из вероятных причин - некорректная работа с памятью где-то еще.


Исключено. Дописываю менджер процессов к хорошо отлаженому и давно работающему серверу

Цитата:
Здесь четыре (вместо одного) раза выполняется поиск в map. Лучше использовать insert.


Понял.

Цитата:
Здесь можно заменить const_iterator на iterator и через него удалять элемент: pmap.erase(it).


Понял.

Цитата:
А удаляешь случайно не через delete? Разве new char[maxlength] не проще написать?


free(), привычка.

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

4
30 марта 2004 года
mike
3.7K / / 01.10.2002
Цитата:
Originally posted by Winnie
Майк какой компилятор?
В VS 6.0 есть баги в реализации STL (какие именно сложно сказать).
Если на ней делаешь - попробуй собрать проект на VS 7.0, там вроде лучше реализован STL или найди STLport и его попробуй вместо стандартного.



gcc version 2.95.3 20010315 (release) [FreeBSD]

:P

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог