Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.64/141: Рейтинг темы: голосов - 141, средняя оценка - 4.64
3 / 3 / 1
Регистрация: 11.03.2019
Сообщений: 42

Как уничтожить экземпляр класса (объект)?

21.06.2019, 16:48. Показов 30467. Ответов 119

Студворк — интернет-сервис помощи студентам
Я столкнул с такой проблемой. Я не могу понять как удалять объекты класса(экземляры). Читая интернет я вижу что "мусорщик" должен автоматически удалять те объекты, на которые нет указателя, но у меня это не работает. Подскажите как решить. Вот видео где всё показано, по нажатию кнопки в указатель записывается новый объект, но старый не удаляется, это видно по увеличению кол-ва оперативной памяти занимаемого приложением.

https://www.youtube.com/watch?... e=youtu.be
Кликните здесь для просмотра всего текста
1
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.06.2019, 16:48
Ответы с готовыми решениями:

Как в случае с Dependency Injection внедрять отдельный экземпляр некоторого класса только лишь для одного другого класса
Здравствуйте, пытаюсь понять как же всё таки правильно использовать Dependency Injection в случае c ASP.NET Web Api2 и Entity Framework 6...

Как увидеть объект Session и объект Server из модуля класса?
В модуле класса пишу: 'Provider=Microsoft.Jet.OLEDB.4.0;' & _ 'Data Source=' & Server.MapPath('../InterDict.mdb')...

Как создать экземпляр класса по условию
Доброго времени суток. Нужна помощь в решении следующей задачи: Исходные данные Имеется решение типа WindowsFormsApplication. В нем,...

119
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
28.06.2019, 17:18
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от skilllab Посмотреть сообщение
Что говорит о том, что Dispose() это всего лишь Интерфейс, указывающий программисту не забыть обнулить ссылки на неуправляемые ресурсы
А чем по вашему деструктор то занимается? Именно высвобождением ресурсов.
0
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,051
Записей в блоге: 1
28.06.2019, 17:22
Цитата Сообщение от amr-now Посмотреть сообщение
что-то Вас не туда занесло
Ну, что у MS написано то и скопипастил)))
Цитата Сообщение от amr-now Посмотреть сообщение
Dispose() именно в первую очередь предназначен для вызова Dispose()/Close() классов с неуправляемыми ресурсами.
Я и не настаивал на обратном.
Цитата Сообщение от amr-now Посмотреть сообщение
А обнуление ссылок в целом лишний шаг. Просто типа красиво.
Ну, не смогу вам найти с ходу ссылок, но знаю что unmanaged ресурсы нужно (крайне рекомендовано) вручную освобождать от ссылок при уже неиспользуемом классе. Что достигается null значением
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
28.06.2019, 17:24
Цитата Сообщение от amr-now Посмотреть сообщение
А обнуление ссылок в целом лишний шаг. Просто типа красиво.
Да вот ничего подобного. Без ручного вызова Dispose и осовобждения ресурсов они не высвободятся до следующей уборки. Т.е. в общем случае вообще никогда.
При этом в подавляющем большинстве графов ссылок характерным для ООП GC без предварительного принудительного разрыва взаимосвязей вообще ничего убрать не в состоянии даже при принудительном запуске уборки.
Никакой автоматики в вопросе управления жизненным циклом инстансов GC не дает в принципе. А отсюда и склонность к утечкам и некорректному с точки зрения ООП поведению. И лечение этих болячек абсолютно аналогично ручному высвобождению памяти/разрушению инстансов в языках без какой либо автоматики вообще. Вот для этого Disposе и прикостылили - полный аналог паскалевских деструкторов с ручным вызовом.
0
 Аватар для skilllab
296 / 236 / 58
Регистрация: 03.02.2011
Сообщений: 2,051
Записей в блоге: 1
28.06.2019, 17:24
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Именно высвобождением ресурсов.
Да, тех самых managed. Насколько помню, просто обнуление ссылки на класс, содержащий unmanaged ресурс, может и не дать понять GC что тот самый unmanaged ресурс нужно освободить прям сейчас в самое ближайшее время. Может получиться такая противная штука как RPC_E_DISCONNECTED.
0
Эксперт JS
6497 / 3908 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
28.06.2019, 17:27
skilllab, у MS не все абзацы информации о Dispose() являются актуальными и/или стопроцентно правильными для практического применения.
null просто позволяет разрезать ветки объектов на более мелкие ветки, что в целом не является обязательным. Общая логика учёта памяти сами программистом играет намного большую роль.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
28.06.2019, 18:02
Цитата Сообщение от skilllab Посмотреть сообщение
Может получиться такая противная штука как RPC_E_DISCONNECTED.
Может получится такая штука что к примеру видеопамять закончилась и при этом ссылки на хандлеры держащие буфера потеряны. Но GC их не высвободит, потому что управляемой им памяти еще вагон и маленькая тележка и уборку он может и вообще не запустить.

Добавлено через 2 минуты
Цитата Сообщение от amr-now Посмотреть сообщение
Общая логика учёта памяти сами программистом играет намного большую роль.
И это теперь называется автоматика. Почему с ручным управлением памятью об этом вообще думать не надо?

Добавлено через 26 минут
Цитата Сообщение от amr-now Посмотреть сообщение
просто позволяет разрезать ветки объектов на более мелкие ветки, что в целом не является обязательным.
Только вот во многих графах ссылок GC вообще ничего без такой разрезки мусором не посчитает. Мало того при удалении инстансов в ООП задача абсолютно противоположна той которая решается GC - поиску буферов не имеющих трассы на рут. В ООП список удаляемых инстансов всегда заранее известен а какие у них есть трассы на момент удаления никого не колышит. Поэтому необходимо обнулить все ссылки на элементы удаляемого списка из других инстансов, не входящих в список удаления. Иначе GC вообще ничего убрать не сможет.
0
Эксперт .NET
 Аватар для Usaga
14733 / 9507 / 1363
Регистрация: 21.01.2016
Сообщений: 35,869
30.06.2019, 07:02
Fulcrum_013, Dispose занимается ровно тем, что в нём будет написано. За уничтожение объекта этот метод не отвечает. Прекращайте нести бред откровенный.
1
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.06.2019, 07:22
Цитата Сообщение от Usaga Посмотреть сообщение
Dispose занимается ровно тем, что в нём будет написано
Точно так же деструктор занимается ровно тем что в нем будет написано. И точно так же не уничтожает буфер. И тот и другой отвечают за приведение инстанса в состояние безопасное для удаления буфера. Это и называется разрушение инстанса. Идите учите матчасть.
0
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
30.06.2019, 16:18
Fulcrum_013, какое это имеет отношение к изначальному вопросу об уничтожении managed обьекта?
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.06.2019, 18:39
nicolas2008, Прямое. Принудительное уничтожение инстанса осуществляется только вручную вызовом специально написанного для этого Dispose. Буфер же объекта когда нибудь потом заберет GC. При этом без такого ручного уничтожения инстанса уборка может и вообще не состоятся что скорее всего у ТС и происходит.
0
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
30.06.2019, 22:33
Fulcrum_013, может хватит уже демонстрировать свое невежество?
В C++ есть операторы new и delete, которые служат для создания и удаления обьекта соответственно.
В .NET есть только new, а аналога delete нету.
Вопрос автора был более чем конкретен. А ваши пространственные рассуждения и вымышленная класификация удалений никого не интересуют. Не надо усложнять и разводить ложную философию.
Удаление обьекта - это освобождение памяти обьекта. Dispose - это вспомогательная фича .NET для детерминированного во времени удаления связанных unmanaged ресурсов, которыми владеет данный обьект. Сам обьект удаляется только сборщиком мусора.
2
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
01.07.2019, 00:06
nicolas2008, Хватит демонстрировать ваше невежество.
В с++ есть операторы new и delete которые создают и уничтожают буфер в куче. А так же есть автоматическое управление жизненным циклом объекта, которое гарантрует автоматический вызов конструктора сразу после выделения буфера типа класса и деструктора перед удалением такого буфера, которая работает для инстансов размещенных где угодно (на стеке, в теле хозяина) а не только на куче.
В шарпе автоматика управления жизненным циклом объекта отсутсвует от слова совсем. Удалением же буферов GC занимается отложенно. Но инстанс живущий в буфере все равно разрушать необходимо вовремя (сразу при выходе из скопа, обнулении ссылки и т.п.) а не отложенно для обеспечения корректности поведения. Вот для этого Dispose - аналог деструктора с ручным вызовом и прикрутили.
Вот об этом автор вопроса как раз и спрашивает.

Добавлено через 5 минут
Цитата Сообщение от nicolas2008 Посмотреть сообщение
Удаление обьекта - это освобождение памяти обьекта.
Не путайте объект из описания работы GC и объект в терминах ООП. Это две гигантские разницы и в документации на языке оригинала именуются разными словами.

Добавлено через 2 минуты
Цитата Сообщение от nicolas2008 Посмотреть сообщение
Сам обьект удаляется только сборщиком мусора.
Сборщик мусора не оперирует инстансами (экземплярами классов). Он оперирует буферами. Поэтому не надо путать удаление инстанса которое подчиняется правилам ООП и удаление буфера который и есть тем объектом которым управляет GC.
Они живут по разным правилам. И именно то что эти правила абсолютно противоположны и делает GC абсолютно бесполезным в ООП-языке.
0
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
01.07.2019, 01:06
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А так же есть автоматическое управление жизненным циклом объекта, которое гарантрует автоматический вызов конструктора
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
В шарпе автоматика управления жизненным циклом объекта отсутсвует от слова совсем.
Шта? В .NET уже и конструкторы отменили?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
выделения буфера типа класса
Тарабарщина какая то) Можно ссылочку на (авторитетный) источник, где обьясняется что такое "буфер типа класса"? А то я, невежда, наверное мало книжек читал, раз не встречал нигде такой терминологии.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
в теле хозяина
Спасибо, что не повелителя

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Но инстанс живущий в буфере все равно разрушать необходимо вовремя (сразу при выходе из скопа, обнулении ссылки и т.п.) а не отложенно для обеспечения корректности поведения. Вот для этого Dispose - аналог деструктора с ручным вызовом и прикрутили.
Что такое "корректное поведение" ?

Я тут подготовив пару примерчиков. И... о чудо! GC смог удалить обьекты без ручного вызова Dispose? Как так получилось? Теперь у приложения будет "некорректное поведение"?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        static void Main(string[] args)
        {
            var obj = new MyClass();
            var objWeakRef = new WeakReference(obj);
 
            obj = null;
            GC.Collect();
 
            Console.WriteLine($"Object is {(objWeakRef.IsAlive ? "alive" : "deleted")}");        
            Console.ReadLine();
        }
 
        class MyClass
        {
        }
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
        static void Main(string[] args)
        {
            var externalService = new ExternalService();
 
            var obj = new MyClassWithSomeRef(externalService);
            var objWeakRef = new WeakReference(obj);
 
            obj = null;
            GC.Collect();
 
            Console.WriteLine($"Object is {(objWeakRef.IsAlive ? "alive" : "deleted")}");        
            Console.ReadLine();
        }
 
        class MyClassWithSomeRef
        {
            private ExternalService _externalService;
 
            public MyClassWithSomeRef(ExternalService externalService)
            {
                _externalService = externalService;
            }
        }
 
        class ExternalService
        {
        }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        static void Main(string[] args)
        {
            var obj = new MyClassWithUnmanagedResource();
            var objWeakRef = new WeakReference(obj);
 
            obj = null;
            GC.Collect();
 
            Console.WriteLine($"Object is {(objWeakRef.IsAlive ? "alive" : "deleted")}");        
            Console.ReadLine();
 
            // Что здесь некорректного c обьектом obj кроме того что получим утечку памяти (_unmanagedResourceRef)?
        }
 
        class MyClassWithUnmanagedResource
        {
            private IntPtr _unmanagedResourceRef;
 
            public MyClassWithUnmanagedResource()
            {
                _unmanagedResourceRef = Marshal.AllocHGlobal(1024 * 1024);
            }
        }
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
        static void Main(string[] args)
        {
            var obj = new MyClassWithUnmanagedResource();
            var objWeakRef = new WeakReference(obj);
 
            obj = null;
            GC.Collect();
 
            Console.WriteLine($"Object is {(objWeakRef.IsAlive ? "alive" : "deleted")}");        
            Console.ReadLine();
 
            // А тут вообще утечки не будет. _unmanagedResourceRef освобожден сборщиком мусора. Магия?
        }
 
        class MyClassWithUnmanagedResource
        {
            private IntPtr _unmanagedResourceRef;
 
            public MyClassWithUnmanagedResource()
            {
                _unmanagedResourceRef = Marshal.AllocHGlobal(1024 * 1024);
            }
 
            ~MyClassWithUnmanagedResource()
            {
                Marshal.FreeHGlobal(_unmanagedResourceRef);
            }
        }
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
01.07.2019, 01:08
Цитата Сообщение от nicolas2008 Посмотреть сообщение
Шта? В .NET уже и конструкторы отменили?
Это сложно назвать управлением жизненным циклом. Скорее управление инициализацией.

Добавлено через 45 секунд
Цитата Сообщение от nicolas2008 Посмотреть сообщение
Что такое "корректное поведение" ?
Уничтожение инстансов в соответсвии с правилам ООП.
0
01.07.2019, 01:26

Не по теме:

Fulcrum_013, умный человек умеет признать свои ошибки (это не о вас).

0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
01.07.2019, 01:26
Цитата Сообщение от nicolas2008 Посмотреть сообщение
GC смог удалить обьекты без ручного вызова Dispose?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
class MyClass{
   int id; 
public:
  MyClass(int aid) :id(aid)   {}
  ~MyClass(){ std::cout << " instace destroyed  id:" << id <<std::endl; }
};
void main(){
  std::cout <<"outer scope start"<<std::endl;
  { 
     MyClass a(1) ;
     std::cout <<"inner scope start"<<std::endl;
     {
          MyClass b(2);
     }
     std::cout <<"inner scope start"<<std::endl;
  }
  std::cout <<"outer scope end" <<std::endl;
}
Цитата Сообщение от nicolas2008 Посмотреть сообщение
тут подготовив пару примерчиков. И... о чудо! GC смог удалить обьекты без ручного вызова Dispose? Как так получилось? Теперь у приложения будет "некорректное поведение"?
А теперь попробуйте изобразите вот такой примерчик без вызова Dispose(); А в графах ссылок характерных для паттернов ООП без разрыва взаимосвязей которое необходимо производить инстантно при выходе инстанса из скопа/обнулении/перезаписи ссылки и т.д. GC ничего мусором не посчитает. А соответственно и финализатор который разрывает взаимосвязи не вызовет. Именно по этому и нужен Dispose - потому что вместо современной автоматики управления жизненным циклом по незнанию прикостылили абсолютно устаревший к концу 60-х GC. Кстати устаревший именно по причине невозможности корректного управления жизненным циклом инстансов по правилам ООП и абсолютной неэффективности управления памятью с произвольным доступом, а особенно виртуальной со страничной огранизацией.
0
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
01.07.2019, 01:44
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А теперь попробуйте изобразите вот такой примерчик без вызова Dispose();
Вроде .NET обсуждает а не C++. К чему этот пример?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А в графах ссылок характерных для паттернов ООП без разрыва взаимосвязей которое необходимо производить инстантно при выходе инстанса из скопа/обнулении/перезаписи ссылки и т.д. GC ничего мусором не посчитает. А соответственно и финализатор который разрывает взаимосвязи не вызовет.
Можно пример кода "графа ссылок характерных для паттернов ООП без разрыва взаимосвязей которое необходимо производить инстантно при выходе инстанса из скопа/обнулении/перезаписи ссылки и т.д."?
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
01.07.2019, 01:58
Цитата Сообщение от nicolas2008 Посмотреть сообщение
К чему этот пример?
К тому чего в Net нету от слова совсем но при этом именно это и понадобилось ТС.

Добавлено через 29 секунд
Цитата Сообщение от nicolas2008 Посмотреть сообщение
Можно пример кода "графа ссылок характерных для паттернов ООП без разрыва взаимосвязей которое необходимо производить инстантно при выходе инстанса из скопа/обнулении/перезаписи ссылки и т.д."?
Можно пример графа. и не один.
0
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
01.07.2019, 02:08
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
К тому чего в Net нету от слова совсем но при этом именно это и понадобилось ТС.
Какое отношение это имеет к Dispose?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Можно пример графа. и не один.
Языком молоть не мешки ворочать. Я вам привел пример "графа" с одной ссылкой и сборщик мусора успешно удалил обьект со ссылкой.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
01.07.2019, 02:18
nicolas2008, Там вообще никакого графа нет. И все разруливаемо вооще в компайлтайме.
Вот тут вам пример графа.
C# vs Kotlin
Это без инстаного разрушения инстансов при разрыве ссылок работать не будет в принципе.
Именно поэтому для ООП автоматика нужна именно слежения за жизненным циклом. Тут другие правила удаления. Понятия нужность/ненужность объекта нет. Есть понятие возможность/невозможность существования и оно никак не зависит от наличия ссылок на него со стороны других объектов.
Цитата Сообщение от nicolas2008 Посмотреть сообщение
Какое отношение это имеет к Dispose?
Такое что Dispose - костыль предназначенный для ручной реализации именно такого поведения.

Добавлено через 4 минуты
Цитата Сообщение от nicolas2008 Посмотреть сообщение
Языком молоть не мешки ворочать. Я вам привел пример "графа" с одной ссылкой и сборщик мусора успешно удалил обьект со ссылкой.
Цитата Сообщение от nicolas2008 Посмотреть сообщение
Языком молоть не мешки ворочать. Я вам привел пример "графа" с одной ссылкой и сборщик мусора успешно удалил обьект со ссылкой.
Сборщик не в состоянии обрабатывать слабые ссылки вовремя. Для корректно работы этого костыля необходим запуск GC.Collect после каждого изменения/выхода из скопа ссылки. С чем ТС и столкнулся.
Ну и вооще алгоритмы принято анализировать на примерах наборов данных а не на каком то коде. Код вообще ничего не способен доказать.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.07.2019, 02:18

Как создать экземпляр класса библиотеки
есть сервер создаю прослушку ChannelServices.RegisterChannel(new HttpChannel(60000)); ServerAccess1 ser = new...

Как получить искомый экземпляр класса одной поисковой строкой LINQа
Здравствуйте, Вопрос по LINQ Скажем есть класс Person и есть список этих классов. Person p1 = new Person() { name =...

Ссылка на объект не указывает на экземпляр объекта
Народ, объясните пожалуйста что делаю не так??? Есть класс (Client), из него нужно поменять пару текстовых полей на основной форме...

Ссылка на объект не указывает на экземпляр объекта
всем привет! на днях друг попросил сделать фейк прогу на visual studio, одна получилась все без ошибок работает, а вот остальные вылазиет...

Ссылка на объект не указывает на экземпляр объекта.
Добрый день. При выполнении кода: dynamic zapros_cena = ExecuteCreateObject(baza, &quot;NewObject&quot;, new object { &quot;Запрос&quot;...


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

Или воспользуйтесь поиском по форуму:
80
Закрытая тема Создать тему
Новые блоги и статьи
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru