Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
ganimed
0 / 0 / 1
Регистрация: 27.07.2010
Сообщений: 3
1

Обработка списков

05.10.2010, 12:54. Просмотров 993. Ответов 2
Метки нет (Все метки)

Программа работы со списками написана, для малых списков (малых по объему занимаемой памяти) она работает адекватно: список строится, обрабатывается, удаляется. Если же размер списка больше некоторого значения, то программа по-прежнему его строит, но не может никаким образом обработать. Просмотр списка идет до определенного узла, после чего программа вылетает с ошибкой.

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

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

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

Обработка списков
Помогите защитить учебную практику. Заранее спасибо

Рекурсивная обработка списков
Помогите пожалуйста!!! Очень надо! Дано задание, я весь интернет излазил 2 час думаю, ничего в...

Создание и обработка списков
Даны натуральное число n, действительные числа а1,…, a2n. Получить:...

Обработка списков: функции удаления и поиска элемента
Надо написать функцию Void del (int value) , которая удаляет элемент в списке и Elem *searth (int...

2
fasked
Эксперт С++
5010 / 2589 / 241
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
05.10.2010, 15:36 2
Цитата Сообщение от ganimed Посмотреть сообщение
Вопрос
код бы хоть показали
0
ganimed
0 / 0 / 1
Регистрация: 27.07.2010
Сообщений: 3
06.10.2010, 05:57  [ТС] 3
Лучший ответ Сообщение было отмечено ganimed как решение

Решение

Код? Будет код.

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 ();
}
Из процедуры добавления пустой вызов убрал -- вроде продолжает работать (хвала небесам), но в главной функции он по-прежнему необходим.
0
06.10.2010, 05:57
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.10.2010, 05:57

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

«Хранение и обработка данных с использованием линейных списков».
Вот мне к курсовой работе дали задание.Я не могу его понять, что от меня требуется. Что за система...

Хранение и обработка данных с использованием линейных списков
Люди, помогите пожалуйста!!! Дали задание к курсовой работе. Сделать надо любое из двух (какое...

Обработка списков
Нужен макрос для связки Excel+ADO, или другое решение для ХР, желательно без установки доп....

Обработка списков
Помогите, пожалуйста, с задачей. Необходимо определить новые предикаты, которые работают со...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.