Код C попадает в неожиданную ошибку времени выполнения, если я выполняю циклы последовательно вместо вложенных - PullRequest
0 голосов
/ 29 августа 2018

Полный код здесь . Начальная проблема здесь .

По какой-то причине этот код работает отлично:

for (int i = n - 2; i > -1 ; i--)
{
    if (strcmp(s[i], s[i + 1]) < 0)
    {
        k = i;
        for (int j = n - 1; j > k; j--)
        {
           if (strcmp(s[k], s[j]) < 0)
           {
              l = j;
              swap(s, k, l);
              reverse_sequence(s, k + 1, n - 1);
              return 1;
           }
        }
    }
}

return 0;

При замене внутреннего for на разрыв и написании его после первого для:

for (int i = n - 2; i > -1 ; i--)
{
    if (strcmp(s[i], s[i + 1]) < 0)
    {
        k = i;
        break;
    }
}
for (int j = n - 1; j > k; j--)
{
    if (strcmp(s[k], s[j]) < 0)
    {
        l = j;
        swap(s, k, l);
        reverse_sequence(s, k + 1, n - 1);
        return 1;
    }
}
return 0;

Попадание во время выполнения. Оба печатают правильные варианты.

Что здесь вообще происходит?

Редактировать: если я добавлю

if (i == 0 && k == -1)
        return 0;

после if в первом цикле, он ведет себя как задумано. Таким образом, ясно, что происходит то, что он сравнивает s [-1] (k инициализируется в -1) с чем-то, и он падает.

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Корень вашей проблемы в том, что когда if (strcmp(s[i], s[i + 1]) < 0) всегда ложно, ваш вложенный цикл ведет себя правильно (внутренний цикл for не выполняется), но ваш последовательный цикл for вызовет ошибку, потому что будет выполнено следующее for со значением "k", равным -1 (так как вы говорите, что инициализируете k с -1), и вы будете выполнять доступ к массиву вне буфера (str [-1]).

Условие if, добавленное вами для исправления вашего последовательного цикла for, в точности соответствует тому, что первый вложенный цикл делает неявно: если он не найден, ничего не делать.

0 голосов
/ 29 августа 2018

Нельзя просто заменить вложенные циклы for последовательными циклами for, если внутренний цикл for каким-то образом зависит от управляющего выражения внешнего цикла for.

В этом случае управляющее выражение внутреннего цикла for зависит от k, равного i, а управляющее выражение внешнего цикла зависит от i.

Попробуйте это с простыми циклами for, и вы поймете. Ошибка времени выполнения во втором случае, вероятно, вызвана из-за некоторого доступа к памяти за пределами допустимого диапазона, поскольку значение k больше не регулируется значением i.

...