Почему std :: strlen () работает с массивами символов БЕЗ завершающих нулевых символов? Это оптимизация компилятора?

Другое решение ... быстро «повторно использовать» ваш C # в PowerShell (коды кода на C # теряются где-то в сети).

Add-Type -TypeDefinition @"
    using System.Text;
    using System.Globalization;

    public class Utils
    {
        public static string RemoveDiacritics(string stIn)
        {
            string stFormD = stIn.Normalize(NormalizationForm.FormD);
            StringBuilder sb = new StringBuilder();

            for (int ich = 0; ich < stFormD.Length; ich++)
            {
                UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
                if (uc != UnicodeCategory.NonSpacingMark)
                {
                    sb.Append(stFormD[ich]);
                }
            }
            return (sb.ToString().Normalize(NormalizationForm.FormC));
        }
    }
"@ | Out-Null

[Utils]::RemoveDiacritics("ABC-abc-ČŠŽ-čšž")
1
задан πάντα ῥεῖ 17 January 2019 в 17:37
поделиться

2 ответа

Конструкция массивов означает, что любые неиспользуемые слоты удобно устанавливать в нулевой размер.

Итак, то, что вы написали, является абсолютно законным и последовательным.

Если бы вы точно определили размер буфера для «Hello, world!»

char test_cases[4][13]

Вы бы получили «сломанный» ответ и коснулись бы края UB.

Кроме того, поскольку вы объявили, что в качестве первого буфера он будет работать во втором буфере, поэтому даст неправильный ответ, а не какую-то фатальную ошибку.

На самом деле, посмотрев еще раз, поскольку вы определили вторую строку как пустую, вы ВСЕ ЕЩЕ не увидите ошибку, поскольку первый байт переполненных данных, возможно, также заполнен нулями!

Я говорю, возможно, потому что {} без значения на самом деле НЕ является допустимым C. Это допустимый C ++ 11, но я не совсем уверен, должно ли поведение гарантировать, что все члены обнуляются, если C ++ 11 агрегированные инициализаторы "style" вызываются. Фактически, из-за вашего вывода {}, должно быть, сделал "правильную" вещь.

Обычно в памяти так много нулей, что ваши строки обычно заканчиваются в конце концов! Как упомянул @Джон, для иностранцев это возможность украсть деньги с вашего банковского счета.

0
ответ дан Gem Taylor 17 January 2019 в 17:37
поделиться

говорит, что передача массива char с нулевым символом в конце в std :: strlen является неопределенным поведением

Правильно.

Однако приведенный ниже код работает просто отлично.

Все строки имеют значение с нулевым завершением и поэтому не имеют неопределенного поведения.

Несмотря на это, вы не можете предположить, что программа с неопределенным поведением не будет работать "отлично". В этом нет ничего необычного.

и, скорее всего, приведет к сбою программы.

Не стоит ожидать, что неопределенное поведение "может вызвать сбой программы". UB вполне может не вызвать сбой программы.

0
ответ дан eerorika 17 January 2019 в 17:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: