// =========================================================================== // ОДНА ЗАДАЧА НА ЧЕТЫРЁХ ЯЗЫКАХ — 3/4: C# (.NET) // Задача: скопировать строку в буфер размером ровно 16 символов. // // Запуск (если установлен .NET SDK): dotnet run // Онлайн, без установки: dotnetfiddle.net // =========================================================================== using System; class CopyName { static void Main() { Console.OutputEncoding = System.Text.Encoding.UTF8; char[] buffer = new char[16]; // буфер: ровно 16 символов string source = "Иванова Анна Петровна, отдел информационной безопасности"; Console.WriteLine($"Длина исходной строки: {source.Length}"); Console.WriteLine($"Размер буфера: {buffer.Length}"); Console.WriteLine(); try { // Тот же цикл, та же логическая ошибка: идём по длине источника. for (int i = 0; i < source.Length; i++) { buffer[i] = source[i]; } Console.WriteLine("Скопировано без ошибок — этого не произойдёт."); } catch (IndexOutOfRangeException error) { Console.WriteLine("Среда выполнения остановила запись за границу буфера:"); Console.WriteLine($" {error.Message}"); } // ------------------------------------------------------------------- // А вот как эта задача решается правильно. Обратите внимание: // цикл ограничен МЕНЬШЕЙ из двух длин, а не длиной источника. // ------------------------------------------------------------------- int limit = Math.Min(source.Length, buffer.Length); for (int i = 0; i < limit; i++) { buffer[i] = source[i]; } Console.WriteLine($"Безопасная копия: «{new string(buffer, 0, limit)}»"); } } // =========================================================================== // ЧТО ЗДЕСЬ ВАЖНО УВИДЕТЬ // // Проверку границ массива в C# нельзя отключить настройкой сборки. // Она встроена в среду выполнения (CLR) и работает всегда — в отличие // от {$RANGECHECKS} в Pascal, который можно выключить. // // В самом управляемом массиве проверка сохраняется. Отдельную границу // создают unsafe-код, FFI/P/Invoke и нативные зависимости: они требуют // разрешения сборки, ревью и собственных мер контроля. // Именно поэтому в правилах кодирования (процесс 5.8 ГОСТ Р 56939-2024) // для C#-проектов обычно прямо записывают: «блоки unsafe запрещены, // исключения согласуются с архитектором». // // Языки, где безопасность памяти обеспечивается средой выполнения или // компилятором, называют memory-safe: C#, Java, Python, Go, Rust. // Языки, где она лежит на программисте: C, C++, ассемблер. // По данным Microsoft Security Response Center, около 70 % уязвимостей // в продуктах Microsoft за 2006–2018 годы относились к классу нарушений // безопасности памяти. Управляемый C# устраняет многие такие ошибки, но // unsafe-код и нативные границы требуют отдельного контроля. // ===========================================================================