Моя программа падает на машине с Windows, но на Linux она работает нормально - PullRequest
0 голосов
/ 07 февраля 2019

Я попытался запрограммировать функцию Ackermann на своем ноутбуке (Win10), однако программа потерпела крах при более высоких значениях вместо того, чтобы продолжать вычислять в течение нескольких минут или часов.

Мой друг пробовал тот же код на своем компьютере(SUSE), и он работал просто отлично, затем мы попробовали его на школьном сервере (CentOS), и он снова рухнул.

РЕДАКТИРОВАТЬ: Он работал и на сервере, просто нужна была вторая попытка.Он также работал на другом сервере, который мы пробовали ... Все это в Linux.

Мы подозреваем, что переполнение стека стоит за этим, но это странно, потому что значения еще не слишком высокие.Как я могу тогда выполнить рекурсивные функции в этой системе?

Спасибо за все ответы.Мне просто любопытно, почему это происходит и как заставить это работать на моей машине.

Я пытался использовать C и C ++ без изменений.

#include <stdio.h>

int ackermann (int m, int n);

int main () {

  int m = 4;
  int n = 1;

  return ackermann(m,n);
}

int ackermann (int m, int n)
{
  if      (m == 0)          return n=n+1;
  else if (m > 0 && n == 0) return ackermann(m-1,1);
  else if (m > 0 && n > 0)  return ackermann(m-1,ackermann(m,n - 1));
}

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

В Visual Studio размер стека по умолчанию составляет 1 МБ, поэтому с глубиной рекурсии 65535 и, как я полагаю, минимальный кадр стека для вызывающей функции / функции на x64 этого типа составляет 72 байта, поэтому у вас закончитсядоступное пространство кадра стека для вашей программы (я вычисляю почти 4,5 МБ стека, необходимого для этого сценария).Это также приводило к ошибке переполнения буфера стека и не имеет ничего общего с разрушением стека, за исключением того, что вы превысили максимальный размер стека, доступный вашей программе при компиляции.

Большинство компиляторов, включая Visual Studio, позволяют указывать размер стека.

Подробнее: https://docs.microsoft.com/en-us/cpp/build/reference/f-set-stack-size?view=vs-2017

[Отредактировано для отображения 65 535 кадров, а не 1,4 миллиарда]

0 голосов
/ 07 февраля 2019

Звучит так, как будто он разбивает стек, или, точнее, переполнение буфера в стеке , то есть сообщение об ошибке, которое вы получили.Функция имеет очень большую глубину и будет продолжать помещать переменные в стек.Если вы поместите достаточное количество переменных в стек, он будет разбитУ компьютера нет бесконечной памяти для стека и, судя по его звукам, тоже не сумасшедшая сумма.

При достаточно большом входном сигнале он должен составлять любой удар, если он не оптимизирован должным образом (и может все равно произойти),Не зная больше о вашем компиляторе, не может быть исчерпывающей опции, как отключить его, но если вы используете пакет компилятора Microsoft Visual Studio, вы можете отключить защиту , если я правильно понимаю этот документ .

  1. В обозревателе решений щелкните правой кнопкой мыши проект и выберите Свойства
  2. В диалоговом окне "Страницы свойств" выберите папку C / C ++.
  3. Нажмитестраница свойств генерации кода.
  4. Измените свойство проверки безопасности буфера.

В качестве предупреждения это небезопасно и могут случиться плохие вещи, поэтому используйтеэто на свой страх и риск.

...