Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
1

Не выполняется realloc

03.06.2012, 13:35. Показов 3880. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вообщем, не могу понять в чем ошибка, malloc() работает, а realloc() выдает ошибки. Имеется собственный тип item (структура, в которой два поля, типа char и int), вот тот самый realloc():
C++
1
2
3
4
5
...
   cout<<"перед realloc"<<endl;
   vector=(item *) realloc(vector, size*sizeof(item)); 
   cout<<"realloc выполнен"<<endl;
...
*первое сообщение выводится, а то, что после realloc'а - нет.

vector - указатель типа item
size - кол-во элементов, для которых требуется место

P.S. IDE - code::blocks
OC Linux (Ubuntu)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.06.2012, 13:35
Ответы с готовыми решениями:

Код не выполняется в одном месте, но выполняется в другом
Вот код процедуры: LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)...

Проект выполняется на Windows 8, но не выполняется на виртуальной машине
У меня есть проект, собранный в релиз, в котором осуществляется внедрение своей dll в память чужих...

не выполняется запрос в коде, но выполняется в phpliteadmin
всем привет! необходима небольшая помощь, есть бд с таблицей &quot;keys&quot; и одной из колонок в ней -...

realloc
здраствуйте! решил накатать такой класс #include &lt;stdlib.h&gt; template &lt;typename TYPE&gt; ...

20
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
03.06.2012, 13:41 2
Цитата Сообщение от yoloyol Посмотреть сообщение
а realloc() выдает ошибки
текст ошибки какой?
0
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
03.06.2012, 13:48  [ТС] 3
Цитата Сообщение от Jupiter Посмотреть сообщение
текст ошибки какой?
к сожалению, не получается скопировать его, сделал скрин:
Миниатюры
Не выполняется realloc  
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
03.06.2012, 13:53 4
перед realloc-ом выведи size, мб он не инициализирован
0
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
03.06.2012, 14:00  [ТС] 5
Цитата Сообщение от Jupiter Посмотреть сообщение
перед realloc-ом выведи size, мб он не инициализирован
да нет, даже не в этом дело, указывал и просто число вместо size'а, все равно не помогло.

Добавлено через 4 минуты
когда выходит ошибка: "invalid next size: 0x094b5178 ***"
она указывает на адрес указателя "vector", может это как-то поможет разобраться в ошибке?!
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
03.06.2012, 14:09 6
А как инициализировался указатель до realloc?
0
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
03.06.2012, 14:12  [ТС] 7
Цитата Сообщение от Toshkarik Посмотреть сообщение
А как инициализировался указатель до realloc?
он у меня в классе (в котором объявлена структура item), был объявлен так: "item * vector";
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
03.06.2012, 14:17 8
realloc применяется только к инициализированному указателю... Или присваивайте ему изначально 0, или первый раз выделяйте память с помощью malloc или calloc.

Добавлено через 3 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
Или присваивайте ему изначально 0
Тут я имел ввиду при создании объекта а не перед каждым realloc.
0
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
03.06.2012, 14:17  [ТС] 9
Цитата Сообщение от Toshkarik Посмотреть сообщение
realloc применяется только к инициализированному указателю... Или присваивайте ему изначально 0, или первый раз выделяйте память с помощью malloc или calloc.
Сперва я выделил для него память, при помощи malloc(), после начал заносить в память значения и когда ее уже не осталось (а данные надо было куда-то вводить) я вызвал realloc().
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
03.06.2012, 14:18 10
Выложите весь код тогда уже, иначе мы так будем очень долго гадать
0
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
03.06.2012, 14:52  [ТС] 11
Цитата Сообщение от Toshkarik Посмотреть сообщение
Выложите весь код тогда уже, иначе мы так будем очень долго гадать
хорошо, но не судите строго, за "неграмотность")

Добавлено через 5 минут
"vector.h"
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
using namespace std;
 
class list
{
    public:
        list();
        ~list();
        void sizeVector();  //размер вектора
        void fillNext();    //заполнить поля next
        void menu();    //меню, список действий     //*==
        void completionList(ifstream & fin);  //заполнение списка
        void insertEl();    //вставка элемента
        void deleteEl();    //удаление элемента
        void copyEl();      //буферизация элемента
        void replaceEl();   //замена элемента
        void listEmpty();   //список пуст?
        void contentsList();    //содержимое списка
        void output();      //вывод в файл      //*==
        //void spareMemory(); //резервирование памяти (malloc)
 
    private:
        int size, topLevel;
        char bufferEl;    //переменная хранящая скопированного эл
        struct item
            {
                char element;
                int next;
            };
 
        struct tag
            {
                int head;    //начало списка
                int curr;     //текущий элемент
                int predCurr; //предыдущий элемент
                int headNull;   //начало пустой цепочки
            };
        item * vector;
        tag dataList;
};
"vector.cpp"
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include "vector.h"
 
using namespace std;
 
ifstream fin;
 
list::list()    //конструктор
{
    size=10;
    topLevel=0;
    bufferEl=NULL;
    dataList.head=0;
}
 
list::~list()   //деструктор
{
 
}
 
void openFile (ifstream & fin) //открытие файла (для чтения)
{
    cin.ignore();    //отчитска потока ввода
    char inFile[255];
    cout<<"Открыть файл: "<<endl;
    cin.getline(inFile, 255);
    fin.open(inFile);
    //cout<<"Открытие выполнено"<<endl;
    while (!fin)
        {
            cout<<"\nФайл не найден!\nВведите существующий файл:"<<endl;
            cin.getline(inFile, 255);
            fin.open(inFile);
        }
}
 
void list::menu()
{
    int choice; //вариант из списка
    cout<<"Выберите из списка одну из операций: "<<endl;
    cout<<"1. Заполнить список элементми из файла"<<endl;
    cout<<"2. Вставка элемента в список"<<endl;
    cout<<"3. Удаление элемента из списка"<<endl;
    cout<<"4. Замена элемента в списке"<<endl;
    cout<<"5. Проверка статуса списка"<<endl;
    cout<<"6. Вывод содержимого списка"<<endl;
    cout<<"7. Вывод результата работы в файл"<<endl;
    cout<<"0. Выход из программы\n"<<endl;
    cin>>choice;
    switch(choice)  //рассмотреть вывод операций, когда список пуст + исп беск вариант + вставка с клавы
    {
        case 1: //откр. и заполнение из файла
            openFile(fin);
            //list::spareMemory();
            list::completionList(fin);
            break;
        case 2: //вставка элемента в списка
            list::insertEl();
            break;
        case 3: //удаление элемента из списка
            list::deleteEl();
            break;
        case 4: //замена элемента из списка
            list::replaceEl();
            break;
        case 5: //проверка статуса списка
            list::listEmpty();
            break;
        case 6: //вывод содержимого списка
            list::contentsList();
            break;
        case 7: //вывод результата работы в файл
            //list::output();
            cout<<"Функция еще не создана"<<endl;
            break;
        case 0: //выход из программы
            exit(0);
        default:
            cout<<"Данной команды не существует. Произведется выходи из программы!"<<endl;
            exit(0);
    }
}
 
void list::sizeVector()  //увеличение вектора (+встр индексация)
{
    size=size*3;  //увел размер
    cout<<"перед realloc"<<endl;
    cout<<"vector= "<<vector<<endl;
    cout<<"size_realloc= "<<sizeof(item)*size<<endl;
    cout<<"size= "<<size<<endl;
    vector=(item *) realloc(vector, size*sizeof(item));  //перераспр память
    cout<<"realloc выполнен"<<endl;
    fillNext(); //вызов фун. индексирования
    cout<<"перераспределение выполнено"<<endl;
}
 
void list::fillNext()    //индексация ячеек
{
    for (int i=topLevel; i<size; i++)  //индексирование ячеек
        vector[i].next=i+1;
    vector[size].next=0;    //последняя яч - указывает на нач. вектора
    vector[0].next=topLevel;    //при перераспределении прявязывает цепочку
    topLevel=size+1; //начало (нового) звена
    cout<<"индексирование выполнено"<<endl;
 
}
 
void list::completionList(ifstream & fin)    //заполнение списка
{
    char ch;
    //if(vector[0].element!='1')  //если список был удален а своб места остались
        vector=(item *) malloc(size*sizeof(item));   //резервация памяти
    cout<<"size_malloc= "<<sizeof(item)*size<<endl;
    fillNext();
    dataList.head=vector[0].next;   //создание головы списка
    cout<<"dataList.head= "<<dataList.head<<endl;
    dataList.curr=dataList.head;    //для перехода по списку
    while(fin.get(ch))
        {
            stepBack:   //чтобы не потерять считанный элемент
            cout<<"***переход***"<<endl;
            if (vector[0].next!=0)  //если не указывает на самого себя
                {
                    vector[dataList.curr].element=ch;   //заносим элемент
                    cout<<"vector[dataList.curr].element= "<<vector[dataList.curr].element<<endl;
                    vector[0].next=vector[dataList.curr].next;  //перебиваем ссылку на пустую ячейку
                    vector[dataList.curr].next=dataList.head;   //указываем на начало списка
                    dataList.curr=vector[0].next;   //смещение по списку +1
                }
            else
                {
                    cout<<"переход в else"<<endl;
                    sizeVector();
                    goto stepBack;
                }
        }
 
}
 
void list::insertEl()    //вставка элемента (доделать для неск эл + из буфера) + (вставлять элемент в пустой список запрещено, для начала нужно его заполнить)
{
    char ch;
    int index;
    cout<<"Введите элемент для вставки: ";
    cin>>ch;
    cout<<"Укажите место вставки: ";
    cin>>index;
    dataList.curr=dataList.head;
    dataList.predCurr=dataList.curr;    //на случай вставки пере 1-м эл
    for (int i=2; i<=index; i++)    //т.к. curr обнуляем до head
            {
                dataList.predCurr=dataList.curr;
                dataList.curr=vector[dataList.curr].next;
            }
 
    stepBack_2: //при перераспред памяти
    if (vector[0].next!=0)
        {
            vector[dataList.predCurr].next=vector[0].next;  //добавляем эл в список
            dataList.predCurr=vector[dataList.predCurr].next;   //перемещ на вставл эл
            vector[0].next=vector[dataList.predCurr].next;  //искл из пустого списка
            vector[dataList.predCurr].next=dataList.curr;   //привязываем цепочку
            vector[dataList.predCurr].element=ch;   //вбиваем знач
        }
    else
        {
            sizeVector();
            goto stepBack_2;
        }
}
 
void list::deleteEl()    //удаление элемента
{
    int index;
    cout<<"Укажите индекс удаляемого элемента: ";
    cin>>index;
    dataList.curr=dataList.head;
    if (vector[dataList.head].next==dataList.head)  //т.е. указ на себя (1эл)
        {
            vector[dataList.curr].next=vector[0].next;  //прицепляю к пустой цепочки
            vector[0].next=dataList.curr;   //связали цепочку с пустым списком
            dataList.head=0;    //т.е. список пуст
            vector[0].element='1';  //для случая когда список пуст и есть свободое место
        }
    else    //если неск эл в списке
        {
            for (int i=2; i<=index; i++)    //т.к. curr обнуляем до head
                    {
                        dataList.predCurr=dataList.curr;
                        dataList.curr=vector[dataList.curr].next;
                    }
            vector[dataList.predCurr].next=vector[dataList.curr].next;  //искл из списка
            vector[dataList.curr].next=vector[0].next;  //прицепили к пустой цепочки
            vector[0].next=dataList.curr;   //связали цепочку с пустым списком
        }
}
 
void list::copyEl()  //копирование элемента
{
    int index;
    cout<<"Укажите индекс элемента, который желаете скопировать: ";
    cin>>index;
    dataList.curr=dataList.head;
    for (int i=2; i<=index; i++)    //т.к. curr обнуляем до head
                dataList.curr=vector[dataList.curr].next;   //доходим до эл
    bufferEl=vector[dataList.curr].element; //копируем элемент
}
 
void list::replaceEl()   //замена элемента   (+из буфера попробовать)
{
    int index;
    char ch;
    cout<<"Укажите индекс элемента, который желаете заменить: ";
    cin>>index;
    cout<<"Введите заменяемый элемент: ";
    cin>>ch;
    dataList.curr=dataList.head;
    for (int i=2; i<=index; i++)    //т.к. curr обнуляем до head
                dataList.curr=vector[dataList.curr].next;   //доходим до эл
    vector[dataList.curr].element=ch; //заменяем элемент
}
 
void list::listEmpty()   //список пуст?
{
    if (dataList.head==0)
        cout<<"Список пуст!"<<endl;
    else
        cout<<"Список не пуст!"<<endl;
    //можно попробовать предложить вывод содержимого списка
}
 
void list::contentsList()    //список содержимого
{
    cout<<"Содержимое списка: "<<endl;
    dataList.curr=dataList.head;
    while (dataList.curr!=dataList.head)
        {
            cout<<vector[dataList.curr].element<<endl;  //вывод эл
            dataList.curr=vector[dataList.curr].next;   //доходим до эл
        }
}
"main.cpp"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include "vector.h"
 
using namespace std;
 
int main()
{
    list object;
 
    object.menu();
    return 0;
}
Добавлено через 25 минут
Цитата Сообщение от yoloyol Посмотреть сообщение
vector[0].next=topLevel; * *//при перераспределении прявязывает цепочку
(104 строка) здесь я баловался на самом деле ее нужно исключить, хотя всё равно работать не будет
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
03.06.2012, 15:07 12
Цитата Сообщение от yoloyol Посмотреть сообщение
хорошо, но не судите строго, за "неграмотность")

Не по теме:

За чтож Вас судить, это форум для помощи а не для суждения :)



У Вас очень быстро растет размер, причем из ничего. При 12 символах в файле, размер увеличивается в конце до 5 314 410. Конечно, когда int переполняется, размер становится отрицательным, и поэтому realloc выдает ошибку. Я не смотрел полностью код, но ошибка в алгоритме перевыделения памяти. И вообще, увеличение размера в 3 раза это как то слишком.
0
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
03.06.2012, 15:10  [ТС] 13
Цитата Сообщение от Toshkarik Посмотреть сообщение

Не по теме:

За чтож Вас судить, это форум для помощи а не для суждения :)



У Вас очень быстро растет размер, причем из ничего. При 12 символах в файле, размер увеличивается в конце до 5 314 410. Конечно, когда int переполняется, размер становится отрицательным, и поэтому realloc выдает ошибку. Я не смотрел полностью код, но ошибка в алгоритме перевыделения памяти. И вообще, увеличение размера в 3 раза это как то слишком.
там я тоже начудил, на самом деле я в полтора раза увеличиваю (size=size*3/2). Работать я буду с данными не больше 50 символов, поэтому вызов перераспределения будет около 5 раз, ведь так?
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
03.06.2012, 15:12 14
В fillNext у Вас выход за пределы массива

Цитата Сообщение от yoloyol Посмотреть сообщение
vector[size].next=0; * *//последняя яч - указывает на нач. вектора
Объекта с индексом size не существует, полагаю тут нужно исправить на size - 1.

Добавлено через 1 минуту
Да дело не в этом, просто даже при увеличении в 3 раза, при 12 символах размер в 5 миллионов какое то вообще не реальное число.
1
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
03.06.2012, 15:22  [ТС] 15
Цитата Сообщение от Toshkarik Посмотреть сообщение
В fillNext у Вас выход за пределы массива



Объекта с индексом size не существует, полагаю тут нужно исправить на size - 1.

Добавлено через 1 минуту
Да дело не в этом, просто даже при увеличении в 3 раза, при 12 символах размер в 5 миллионов какое то вообще не реальное число.
Большое, Вам, спасибо!! Я уже просто замучился, а ошибка была то детская
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
03.06.2012, 15:32 16
Если Вы про выход за пределы массива, то это лишь часть проблемы. Потому что после ее исправления, память у меня так же съедалась, размер не изменился. При каких то 12 символах жрет 40 МБ памяти. Советую Вам пересмотреть реализацию перераспределения памяти и проверку на указание последнего элемента.
0
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
03.06.2012, 15:42  [ТС] 17
Цитата Сообщение от Toshkarik Посмотреть сообщение
Если Вы про выход за пределы массива, то это лишь часть проблемы. Потому что после ее исправления, память у меня так же съедалась, размер не изменился. При каких то 12 символах жрет 40 МБ памяти. Советую Вам пересмотреть реализацию перераспределения памяти и проверку на указание последнего элемента.
разве 40 мб?!
ну вот допустим, я вызвал: vector=(item *) realloc(vector, size*sizeof(item));
до этого size был равен 10, sizeof(item) равен 8, итого: 80 байт.
после перераспределения: 15 * 8 = 120 байт, *(+еще предыдущие 80 байт), итого: 200 байт, а не 40 мбайт
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
03.06.2012, 15:45 18
У меня, при наличии в файле 12 символов, размер в конце равен, как я и писал выше, 5 314 410.
0
0 / 0 / 0
Регистрация: 17.05.2012
Сообщений: 15
03.06.2012, 15:48  [ТС] 19
Цитата Сообщение от Toshkarik Посмотреть сообщение
У меня, при наличии в файле 12 символов, размер в конце равен, как я и писал выше, 5 314 410.
а у меня вроде не так. А могли бы вы показать, как вы проверяете размер занятой памяти?
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
03.06.2012, 16:05 20
Вывод консоли
size_malloc= 80
индексирование выполнено
dataList.head= 0
***переход***
переход в else
перед realloc
vector= 0x8764e0
size_realloc= 240
size= 30
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 1
***переход***
переход в else
перед realloc
vector= 0x8764e0
size_realloc= 720
size= 90
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 2
***переход***
переход в else
перед realloc
vector= 0x8764e0
size_realloc= 2160
size= 270
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 3
***переход***
переход в else
перед realloc
vector= 0x8764e0
size_realloc= 6480
size= 810
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 3
***переход***
переход в else
перед realloc
vector= 0x876d60
size_realloc= 19440
size= 2430
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 2
***переход***
переход в else
перед realloc
vector= 0x8786c0
size_realloc= 58320
size= 7290
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 1
***переход***
переход в else
перед realloc
vector= 0x2f7fd0
size_realloc= 174960
size= 21870
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 1
***переход***
переход в else
перед realloc
vector= 0x3063b0
size_realloc= 524880
size= 65610
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 2
***переход***
переход в else
перед realloc
vector= 0x330f30
size_realloc= 1574640
size= 196830
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 3
***переход***
переход в else
перед realloc
vector= 0x6e0040
size_realloc= 4723920
size= 590490
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 3
***переход***
переход в else
перед realloc
vector= 0x880040
size_realloc= 14171760
size= 1771470
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 1
***переход***
переход в else
перед realloc
vector= 0xd10040
size_realloc= 42515280
size= 5314410
realloc выполнен
индексирование выполнено
перераспределение выполнено
***переход***
vector[dataList.curr].element= 2

Просто перед return 0; в main вставьте какую нибудь функцию для паузы программы. И после того как данные считаются, посмотрите сколько она занимает памяти в диспетчере задач.
0
03.06.2012, 16:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.06.2012, 16:05
Помогаю со студенческими работами здесь

realloc
Столкнулся с проблемой при значениях nStgElm близких к 1000 происходит ошибка выеления памяти...

realloc
Доброго времени суток, есть код, в котором динамически выделяется память под массив, затем этот...

realloc
#include &lt;iostream&gt; using namespace std; int main() { int size=0; cout&lt;&lt;&quot;enter size array:...

Realloc
Программа должна забивать массив command_comblock символами 'p', но она почему-то не выполняет...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru