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

Ваш аккаунт

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

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

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

Меня опять STL map мучает :(

4
11 апреля 2004 года
mike
3.7K / / 01.10.2002
У меня опять проблема с STL. В этом небольшом кусочке кода я пытаюсь сделать следующее:

map - в качестве ключа - int, в качестве значение - структура TProcessInfo

Все вроде работает, но вот почему-то иногда вылетает. gdb ругается именно на работу с map'ом.

Я до этого никогда с STL не работал, может нужно как-то память под структуру выделить, или еще чего.

Код:
// Добавление элемента
void CProcessList::Add(long pid,unsigned long child_num) {
  TProcessInfo pi;

  pi.child_num=child_num;
  pi.user_id=0;
  pi.start=time(NULL);

  pair<int,TProcessInfo> p1(pid,pi);
  pmap.insert(p1);
    }
   
// Удаление элемента
void CProcessList::Delete(long pid) {
return;
    TProcessMap::iterator it = pmap.find(pid);
    if (it!=pmap.end()) pmap.erase(it);
    }
   
// Вывод всех элементов
void CProcessList::DumpInfo(CText *sendtext) {
    int i=1;
    for(TProcessMap::iterator it=pmap.begin();it!=pmap.end();it++) {
        i++;
        sendtext->printf("%d\t%d\t%d\n",i,(*it).first,time(NULL)-(*it).second.start);
        }
    }


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

Код:
class CProcessList {
    private:

        typedef struct {
            int pid;
            time_t start;
            unsigned long user_id;
            unsigned long child_num;
            int mpipe[2];
            } TProcessInfo;

        typedef std::map<int,TProcessInfo> TProcessMap;
        TProcessMap pmap;

    public:
        CProcessList();
        ~CProcessList();

        void Add(long pid,unsigned long child_num);
        void Delete(long pid);

        void DumpInfo(CText *sendtext);
    };
310
11 апреля 2004 года
fellow
853 / / 17.03.2003
Процедура добавления элемента. Здесь меня смущают строки
 
Код:
pair<int,TProcessInfo> p1(pid,pi);
  pmap.insert(p1);

insert для map имеет другую сигнатуру. Пару он возвращает, а вот в качестве параметра не берёт. Да и зачем так сложно. Достаточно ведь:
 
Код:
pmap[pid] = pi;
4
11 апреля 2004 года
mike
3.7K / / 01.10.2002
Спасибо. Все равно вылетает.
Ошибка:

#0 0x8051d2e in _Rb_tree_rebalance (__x=0x807a030, __root=@0x807a004) at /usr/include/g++/stl_tree.h:296
296 __root->_M_color = _S_rb_tree_black;
310
11 апреля 2004 года
fellow
853 / / 17.03.2003
А на чём именно вылетает? На вставке, удалении или выводе?
293
12 апреля 2004 года
SEDEGOFF
586 / / 06.10.2002
br /> class CProcessList {
private:

typedef struct {
int pid;
time_t start;
unsigned long user_id;
unsigned long child_num;
int mpipe[2];
} TProcessInfo;

typedef std::map<int,TProcessInfo> TProcessMap;
TProcessMap pmap;

public:
CProcessList();
~CProcessList();

void Add(long pid,unsigned long child_num);
void Delete(long pid);

void DumpInfo(CText *sendtext);
};
310
12 апреля 2004 года
fellow
853 / / 17.03.2003
auto_ptr в контейнере меня ещё больше смущает. Не думаю, что это хорошо. Ведь при копировании, например, владение указателем у исходного auto_ptr утрачивается. Внутренний же код контейнера может производить различные операции над элементами, в т.ч. и копирование.

Если и держать в контейнере указатели, то уж лучше сырые. Тогда удалять самому придётся.
293
12 апреля 2004 года
SEDEGOFF
586 / / 06.10.2002
Да вроде как не утрачиваеться, я еще проблем с этим не испытывал
310
12 апреля 2004 года
fellow
853 / / 17.03.2003
Контейнеры с auto_ptr нестандартны и непереносимы. Копирование auto_ptr приводит к его модификации (владение указателем у источника утрачивается). Не следует использовать auto_ptr в стандартных контейнерах.

Возвращаясь к сути проблемы, можно вообще отказаться от map. pid содержится в самом TProcessInfo, таким образом можно легко осуществлять поиск по pid, используя стандартный алгоритм и самописный предикат. Сортировка по pid с помощью ст.алгоритма, вставка и прочее, и прочее, и прочее. А контейнер можно использовать любой, хоть list, хоть set, хоть queue, хоть deque.
1
12 апреля 2004 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by mike
Спасибо. Все равно вылетает.
Ошибка:

#0 0x8051d2e in _Rb_tree_rebalance (__x=0x807a030, __root=@0x807a004) at /usr/include/g++/stl_tree.h:296
296 __root->_M_color = _S_rb_tree_black;


Для решения подобной задачи я использовал связку multiset+map+static-переменная.
И вставлял в мап итератор на элемент контейнера multiset

Код:
int TClass::insertClass(const TClass& class,int recordId)throw(DuplicateId){
  if(recordId == 0) recordId = nextId++;
  else if(recordId>=nextId) nextId = recordId+1;
  else if(clientcode.count(recordId)){ throw DuplicateId();
  }

  TClass classCopy(class);
  classCopy.SetCode(recordId);
  Class::iterator i = classname.insert(classCopy);
  clientcode[recordId] = i;
  return recordId;
}

А проблема судя по всему в том что, уникальность ключа у тебя не проверяется. Использовать auto_ptr - вряд ли хорошее решение.
3
12 апреля 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by kot_
Использовать auto_ptr - вряд ли хорошее решение.



Ну а если прочитать документацию:

Цитата:
You cannot, however, reliably manage a sequence of auto_ptr<Type> objects with a Standard Template Library container.

7.5K
28 апреля 2004 года
kinosh
1 / / 28.04.2004
Обрати внимание на вот таку мелочь (Выделено жирным):
void CProcessList::Add(long pid,unsigned long child_num) {
pair<int,TProcessInfo> p1(pid,pi);

И еще здесь:
class CProcessList {
private:
typedef struct {
int pid;
......
Это конечно не веская причина ошибок, но может привести к неприятностям, если номер процесса будет слишком большим.
4
28 апреля 2004 года
mike
3.7K / / 01.10.2002
Цитата:
Originally posted by kinosh
Это конечно не веская причина ошибок, но может привести к неприятностям, если номер процесса будет слишком большим.



Неее, в мом случае это синонимы

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