Форум программистов, компьютерный форум CyberForum.ru

Обработка списков - C++

Восстановить пароль Регистрация
 
ganimed
0 / 0 / 0
Регистрация: 27.07.2010
Сообщений: 3
05.10.2010, 12:54     Обработка списков #1
Программа работы со списками написана, для малых списков (малых по объему занимаемой памяти) она работает адекватно: список строится, обрабатывается, удаляется. Если же размер списка больше некоторого значения, то программа по-прежнему его строит, но не может никаким образом обработать. Просмотр списка идет до определенного узла, после чего программа вылетает с ошибкой.

Решение было найдено случайно, и оно мне непонятно. Если при добавлении узла в список после всех основных действий добавить пустой системный вызов (system("")), то все манипуляции со списком любого размера (ну как любого... любого из тех, для которых программа не работала раньше) проходят без проблем. "Странно, -- подумал я. -- Ну бог с ним, главное -- работает!"

Но не тут то было... В процессе дальнейшей работы над программой структура узла списка слегка поменялась, изменился алгоритм обработки и немного расширился набор данных, заносимых в список (это, к слову, записи из системного журнала). Проблема неожиданно вернулась, но уже в иной форме: список строится, обрабатывается, НО не удаляется. И каково же решение? Конечно, дописать пустой системный вызов... Но куда, в процедуру удаления после каждого цикла? Нет! Всего лишь перед вызовом самой процедуры, и этого хватит...

И того, имею бессмысленный вызов system("") после добавления каждого узла в список (из-за чего программа работает сууууущественно дольше) плюс еще один такой же вызов перед удалением всего списка.
Вопрос: почему размер списка влияет на адекватность его обработки программой? И каким образом добавление такого системного вызова помогает решить эту проблему?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.10.2010, 12:54     Обработка списков
Посмотрите здесь:

«Хранение и обработка данных с использованием линейных списков». C++
C++ Список списков)
Хранение и обработка данных с использованием линейных списков C++
Рекурсивная обработка списков C++
C++ слияние списков
Создание и обработка списков C++
C++ Обработка списков

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
fasked
Эксперт C++
 Аватар для fasked
4925 / 2505 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
05.10.2010, 15:36     Обработка списков #2
Цитата Сообщение от ganimed Посмотреть сообщение
Вопрос
код бы хоть показали
ganimed
0 / 0 / 0
Регистрация: 27.07.2010
Сообщений: 3
06.10.2010, 05:57  [ТС]     Обработка списков #3
Код? Будет код.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "EventLog_v2.2.h"
 
#define BUFFER_SIZE 0x07ffff
 
//ÔóГ*êöèÿ ïîèñêГ* Гў Г±ГЁГ±ГІГҐГ¬Г*îì æóðГ*Г*ëå ñîáûòèÿ ГЁГ§ Г§Г*Г¤Г*Г*Г*îãî Г±ГЇГЁГ±ГЄГ* ID
//ГЌГ*éäåГ*Г*ûå ñîáûòèÿ Г§Г*Г*îñÿòñÿ Гў ñïèñîê
void FindEvents (EL_list *);
 
int main (int argc, char * argv[])
{
    EL_list lst;
 
    //Г—ГЁГІГ*ГҐГ¬ æóðГ*Г*Г« Г±ГЁГ±ГІГҐГ¬Г*ûõ ñîáûòèé,
    FindEvents (&lst);
    
    //ÏðîñìГ*òðèâГ*Г¬ ñïèñîê    
    lst.shw_list();
    
    //system ("");
    
    return 0;
}
 
//----------------------------------------------
void FindEvents ( EL_list * lst )
{
    //ÑëóæåáГ*ûå ïåðåìåГ*Г*ûå
    //------------------------------------------
    BYTE                rcd_buffer[BUFFER_SIZE];
    DWORD               dwRead;
    DWORD               dwNeed;
    HANDLE              h;
    EVENTLOGRECORD *    rcd;
    time_t              p_time;
    BYTE *              str;
    //------------------------------------------
    char                msg[201];         //ГЎГіГґГҐГ° ГЇГ*ìÿòè ïîä ñòðîêó Г± ñîîáùåГ*ГЁГҐГ¬
    
    //ÎòêðûâГ*ГҐГ¬ æóðГ*Г*Г« Г±ГЁГ±ГІГҐГ¬Г*ûõ ñîáûòèé
    if ( (h=OpenEventLog(NULL,"System"))==NULL )
        return;
    
    //ÓñòГ*Г*Г*âëèâГ*ГҐГ¬ ГіГЄГ*Г§Г*òåëü äëÿ Г§Г*ГЇГЁГ±ГҐГ© æóðГ*Г*Г«Г* Г*Г* ГЎГіГґГҐГ° ГЇГ*ìÿòè
    rcd = (EVENTLOGRECORD *) &rcd_buffer;
    
    //Г—ГЁГІГ*ГҐГ¬ Г§Г*ГЇГЁГ±ГЁ Гў æóðГ*Г*ëå, ïîêГ* ГЅГІГ® âîçìîæГ*Г®
    while ( ReadEventLog(h,
                         EVENTLOG_BACKWARDS_READ|EVENTLOG_SEQUENTIAL_READ,
                         0,
                         rcd,
                         BUFFER_SIZE,
                         &dwRead,
                         &dwNeed) )
    {
        //ÏîêГ* ГҐГ±ГІГј ïðî÷èòГ*Г*Г*ûå (ГЁ Г*åïðîñìîòðåГ*Г*ûå) Г§Г*ГЇГЁГ±ГЁ, âûïîëГ*ГїГҐГ¬ öèêë
        while ( dwRead>0 )
        {
            //Âû÷èòГ*ГҐГ¬ Г°Г*çìåð ïðîñìîòðåГ*Г*îé Г§Г*ГЇГЁГ±ГЁ ГЁГ§ ГЎГіГґГҐГ°Г*
            dwRead -= rcd->Length;
        
            //Åñëè ID ñîáûòèÿ âêëþ÷åГ*Г® Гў ïåðå÷åГ*Гј èñêîìûõ, Г§Г*Г*îñèì ГҐГЈГ® Гў ñïèñîê
            if ( 1 )
            {
                //Ãîòîâèìñÿ èçûìГ*ГІГј Г¤Г*Г*Г*ûå ГЁГ§ ñîîáùåГ*ГЁГї:
                str = (BYTE *)rcd + rcd->UserSidOffset;
                strncpy (msg,(char *)str,200);
                
                //ÄîáГ*âëÿåì Г*îâûé óçåë ГЄ Г±ГЇГЁГ±ГЄГі
                lst->add_node(rcd->EventID&0x0000ffff,rcd->TimeGenerated,msg,"");
            }
            //ÑìåùГ*ГҐГ¬ ГіГЄГ*Г§Г*òåëü ГЎГіГґГҐГ°Г* Г*Г* ñëåäóþùóþ Г§Г*ГЇГЁГ±Гј
            rcd = (EVENTLOGRECORD *)((LPBYTE)rcd + rcd->Length);
        }
        //ÂñòГ*ГҐГ¬ Г*Г* Г*Г*Г·Г*ëî ГЎГіГґГҐГ°Г* ГЇГ*ìÿòè
        rcd = (EVENTLOGRECORD *) &rcd_buffer;
    }
    CloseEventLog (h);
    
    return;
}
Класс для списка и задействованные методы выглядят так

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*Структура узла списка записей о системных событиях*/
struct EL_node
{
    int         EvtID;      //номер события    
    DWORD       tMrk;       //метка времени 
    char        tstp[25];   //строка со временем регистрации события
    char        msg[201];        //сообщение
    char        infs[50];   //интерфейс
    EL_node *   next;       //указатель на следующий узел списка
};
 
/*Класс для хранения информации о системных событиях*/
//------------------------------------------------------------------------------
class EL_list
{
    private:
        EL_node * head;     //указатель на голову списка
        EL_node * tail;     //указатель на хвост списка
        EL_node * cur;      //указатель на текущий просматриваемый элемент
        int       count;    //количество уклов в списке
        
        void del_list ();   //метод уничтодения списка
                
    public:
        EL_list (): head(NULL), cur(NULL), count (0) {}
        ~EL_list() {del_list();}
        
        void add_node (DWORD,DWORD,char *,char *);    //метод добавления узла
        bool shw_node (int,EL_node *);      //метод поиска указанного узла
        bool shw_node (EL_node *);  //метод последовательлного просмотра списка
        void shw_list ();           //просмотр всего списка
        bool del_node (int);        //метод удаления указанного узла
        bool del_node ();   //метод удаления текущего просматриваемого узла
        int  shw_num  () {return count;}    //количество узлов в списке
        void stp_brs  () {cur = NULL;}      //метод прекращения просмотра списка
};
 
/*Добавление нового узла в список*/
//------------------------------------------------------------------------------
void EL_list::add_node ( DWORD eID, DWORD t_mk, char * p_msg, char * p_infs )
{
    struct EL_node *    tmp;
    struct EL_node      tmp1;
    struct tm *         timeinfo;
    time_t              p_time;
    char                tmp2[25];
    
    timeinfo = new tm;
    tmp = new EL_node;
    
    //Если список пуст, формируем его голову
    if ( head==NULL )
        head = tmp;
    //иначе прикрепляем новый узел в хвост
    else
        tail->next = tmp;
    
    /*Заполняем поля списка*/
    tmp->EvtID = eID;
    tmp->tMrk = t_mk;
    strncpy (tmp->msg,p_msg,200);
    strncpy (tmp->infs,p_infs,49);
    //Формируем метку времени
    p_time = t_mk;
    timeinfo = localtime(&p_time);
    strftime (tmp2,20,"%d.%m.%y [%H:%M]",timeinfo);
    strncpy (tmp->tstp,tmp2,24);
    
    //Делаем добавленный узел хвостом списка
    tmp->next = NULL;
    tail = tmp;
    
    //printf ("(%d)%d %d %s %s %s\n",count,tmp->EvtID,tmp->tMrk,tmp->tstp,tmp->infs,tmp->msg);
    //system ("pause");
    
    //Инкрементируем счетчик узлов
    count++;
    
    delete timeinfo;
    
    //Бессмысленный системный вызов
    //system ("");
}
 
/*Вывод списка на экран*/
//------------------------------------------------------------------------------
void EL_list::shw_list ()
{
    int i = 0;
    int j = 0;
    //Выводим список с головы
    EL_node * crt = head;
    
    //Пока не достигнут конец списка, печатаем данные из узлов
    while ( crt!=NULL )
    {
        printf ("%d %d %d %s %s %s\n",++i,crt->EvtID,crt->tMrk,crt->tstp,crt->infs,crt->msg);
        j += sizeof(*crt);
        crt = crt->next;
    }
    
    printf ("\n--> Total number of nodes: %d\n", count);
    printf ("\n--> Total size of list: %d\n", j);
    //system ("pause");
}
 
/*Удаление списка*/
//------------------------------------------------------------------------------
void EL_list::del_list ()
{
    EL_node * tmp;
    cur = NULL;
 
    while ( shw_node(tmp) )
        del_node ();
}
Из процедуры добавления пустой вызов убрал -- вроде продолжает работать (хвала небесам), но в главной функции он по-прежнему необходим.
Yandex
Объявления
06.10.2010, 05:57     Обработка списков
Ответ Создать тему
Опции темы

Текущее время: 16:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru