2

因此,如果我编写以下代码:

MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);

程序在退出时因访问冲突而崩溃。当我编写这样的代码时:

int a;
a = MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);

它不会崩溃。现在我知道为什么它在崩溃崩溃了,这要归功于我问的另一个问题,也是关于参数不匹配的问题,但我不知道它为什么会崩溃。

那么为什么这会导致 APPCRASH 呢?我一直认为调用具有返回类型的函数而不实际给出返回类型是安全的,例如:

int SomeFunction (void) {
   std::cout << "Hello ya'll!\n";
   return 42;
}

int main (void) {
   int a;

   // "Correct" ?
   a = SomeFunction();
   a = MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);

   // "Incorrect" ?
   SomeFunction();
   MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);

}

当我运行这种“干净”的测试(在新文件中)时,我没有收到任何错误。在我的程序中运行时,它似乎只给出了 MessageBox/MessageBoxA 的错误。了解可能的原因将帮助我查明错误,因为项目代码太大而无法发布(无论如何我都需要我朋友的许可才能发布他的代码)。

附加信息:
编译器 = GCC
平台 = Windows

编辑:

更新
感谢大家迄今为止的反馈。所以我决定通过调试器运行它......现在 Code::Blocks 不会调试项目,除非它是从项目文件 (*.cbp) 加载的 - AFAIK。所以我创建了一个实际项目并将我们项目的主文件复制粘贴到项目中。然后我在调试模式下运行,并没有收到警告。然后我在构建模式下编译并且运行良好。
接下来,我决定在 Dev-C++ 中打开一个新文件并通过调试运行它,然后是最终构建过程,我再次没有遇到任何构建或调试错误。我无法在 Dev-C++ 中重现此错误,即使使用我们的主文件(如在 Code::Blocks 中导致错误的那个)。

结论
故障一定出在 Code::Blocks 上。AFAIK,他们都使用 GCC,所以我很困惑。我唯一能想到的是版本差异或者我的编译器设置或同样模糊的东西。优化器设置或任何其他编译器设置会以某种方式导致这种错误吗?

4

1 回答 1

3

具有返回值的版本不会崩溃,因为它在堆栈上多了一个 int。您的错误代码读取了堆栈的边界,然后遇到访问冲突。但是如果你有更多的堆栈,你将不会点击保护页面,因为这只是足够的额外堆栈。如果错误的代码只读取它是可以的,但仍然损坏。

我们有一点 WTF 诱导代码,如下所示:

char dummy[52];
some_function();

值得庆幸的是,有一条长长的评论解释说删除假人会some_function导致崩溃。它在一个非常古老的应用程序中,所以没有人敢碰它,而且some_function是完全不同的模块,我们无法控制。哦,是的,该应用程序在工业装置(如炼油厂或核电站)中的现场运行平稳超过 20 年...... ^_^

于 2013-04-02T14:01:07.237 回答