我的程序在 Windows 机器上崩溃,但在 Linux 上运行良好

Posted

技术标签:

【中文标题】我的程序在 Windows 机器上崩溃,但在 Linux 上运行良好【英文标题】:My program crashes on the Windows machine yet it works fine on the Linux 【发布时间】:2019-02-06 21:59:16 【问题描述】:

我尝试在我的笔记本 (Win10) 上编写 Ackermann 函数,但是程序在更高的值下崩溃,而不是继续计算几分钟或几小时。

我的朋友在他的机器 (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));

【问题讨论】:

评论不用于扩展讨论;这个对话是moved to chat。 【参考方案1】:

听起来像是堆栈粉碎,或者更准确地说是stack buffer overflow,这是您收到的错误消息。该函数具有非常大的深度,并将继续将变量压入堆栈。如果你将足够多的变量压入堆栈,它就会崩溃。计算机没有用于堆栈的无限内存,从它的声音来看,也不是一个疯狂的数量。

给定足够大的输入,如果没有很好地优化,它应该堆叠任何粉碎(并且可能仍然存在)。在不了解您的编译器的情况下,无法提供有关如何禁用它的全面选项,但如果您使用的是 Microsoft Visual Studio 的编译器套件,则可以禁用保护if I understand this doc correctly。

    在解决方案资源管理器中,右键单击项目,然后单击属性 在“属性页”对话框中,单击 C/C++ 文件夹。 单击代码生成属性页。 修改缓冲区安全检查属性。

作为警告,这是不安全的,并且可能会发生坏事,因此请自行承担风险。

【讨论】:

感谢您的回答,不过我不会冒险。我使用更简单的 IDE,例如 Code::Blocks 和 Dev C++,因为 Visual Studio 是“不合我意”的东西。我只是不相信自己足够开始使用它。现在我对这个问题有了更多的了解,可悲的是,由于我是新来的,我的支持没有显示出来。我只是不明白为什么与 Linux 终端相比,我的堆栈“这么小”:-/【参考方案2】:

在 Visual Studio 中,默认堆栈大小为 1 MB,因此递归深度为 65535,而且我相信这种类型的 x64 上的调用者/函数的最小堆栈帧为 72 字节,因此您将用完您的程序可用的堆栈帧空间(我计算了此场景所需的近 4.5Mb 堆栈)。这也产生了堆栈缓冲区溢出错误,除了您超出了编译时程序可用的最大堆栈大小之外,与堆栈粉碎无关。

包括 Visual Studio 在内的大多数编译器都允许您指定堆栈大小。

更多详情: https://docs.microsoft.com/en-us/cpp/build/reference/f-set-stack-size?view=vs-2017

[经过编辑以反映 65,535 帧,而不是 14 亿帧]

【讨论】:

@TedLyngmo 我修改了我的评论。该问题似乎仍然存在,除非在 Windows 上使用具有更大默认程序堆栈限制的 MSVC 以外的编译器。 是的,在某些环境中肯定会超出堆栈限制。 65536(!) 非常深。

以上是关于我的程序在 Windows 机器上崩溃,但在 Linux 上运行良好的主要内容,如果未能解决你的问题,请参考以下文章

Heroku 当我在线部署我的应用程序时它崩溃但在我的本地机器上它可以正常工作

在 Windows 7 上崩溃但在 XP 上运行

OpenFileDialog 在 Windows XP 下崩溃,但在 Windows 7 下不崩溃

Pyinstaller 一切都在本地机器上运行,但在另一台机器上失败

Android:应用程序在模拟器上运行,但在我的手机上崩溃

如何从远程客户端机器传输到开发团队软件崩溃?