// Добавление элемента
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);
}
}
Меня опять STL map мучает :(
map - в качестве ключа - int, в качестве значение - структура TProcessInfo
Все вроде работает, но вот почему-то иногда вылетает. gdb ругается именно на работу с map'ом.
Я до этого никогда с STL не работал, может нужно как-то память под структуру выделить, или еще чего.
Код:
Вот объявление класса:
Код:
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);
};
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);
};
Код:
pair<int,TProcessInfo> p1(pid,pi);
pmap.insert(p1);
pmap.insert(p1);
insert для map имеет другую сигнатуру. Пару он возвращает, а вот в качестве параметра не берёт. Да и зачем так сложно. Достаточно ведь:
Код:
pmap[pid] = pi;
Ошибка:
#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;
А на чём именно вылетает? На вставке, удалении или выводе?
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);
};
Если и держать в контейнере указатели, то уж лучше сырые. Тогда удалять самому придётся.
Да вроде как не утрачиваеться, я еще проблем с этим не испытывал
Возвращаясь к сути проблемы, можно вообще отказаться от map. pid содержится в самом TProcessInfo, таким образом можно легко осуществлять поиск по pid, используя стандартный алгоритм и самописный предикат. Сортировка по pid с помощью ст.алгоритма, вставка и прочее, и прочее, и прочее. А контейнер можно использовать любой, хоть list, хоть set, хоть queue, хоть deque.
Цитата:
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;
Спасибо. Все равно вылетает.
Ошибка:
#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;
}
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 - вряд ли хорошее решение.
Цитата:
Originally posted by kot_
Использовать auto_ptr - вряд ли хорошее решение.
Использовать auto_ptr - вряд ли хорошее решение.
Ну а если прочитать документацию:
Цитата:
You cannot, however, reliably manage a sequence of auto_ptr<Type> objects with a Standard Template Library container.
void CProcessList::Add(long pid,unsigned long child_num) {
pair<int,TProcessInfo> p1(pid,pi);
И еще здесь:
class CProcessList {
private:
typedef struct {
int pid;
......
Это конечно не веская причина ошибок, но может привести к неприятностям, если номер процесса будет слишком большим.
Цитата:
Originally posted by kinosh
Это конечно не веская причина ошибок, но может привести к неприятностям, если номер процесса будет слишком большим.
Это конечно не веская причина ошибок, но может привести к неприятностям, если номер процесса будет слишком большим.
Неее, в мом случае это синонимы