【问题标题】:c++ segmentation fault (core dumped) with modulus带有模数的c ++分段错误(核心转储)
【发布时间】:2015-03-19 12:05:21
【问题描述】:

我正在开发一个允许用户练习除法的程序。我的代码如下:

//div1
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <algorithm>
using namespace std;

#define CLS "\033[2J\033[1;1H"
#define NEWLINE "\n"

int main() {
    srand(time(NULL));
    int a, div1, div2;
    div1=rand()%11;
    div2=rand()%11;
    while (div2>div1) {
        swap(div1,div2);
        continue;
    }
    if (div1%div2!=0) {
        return main();
    } else {
        cout << CLS;
        cout << NEWLINE;
        do {
            cout << div1 << " / " << div2 << " = ?" << endl;
            cin >> a;
            cout << CLS;
            cout << NEWLINE;
            cout << "\t\tWrong!!" << endl;
            cout << NEWLINE;
        } while (a!=div1/div2);
        cout << CLS;
        cout << NEWLINE;
        cout << "\t\tCorrect!!" << endl;
        cout << NEWLINE;
        cout << "Hit enter to continue." << endl;
        cin.ignore();
        cin.get();
        return main();
    }
    return 0;
}

基本上,它应该做的是首先选择两个随机数。然后,它应该检查第二个数字(div2)是否大于第一个(div1),如果是,它将切换它们。然后,它将使用模数 (div1%div2) 来确保这两个数字可以彼此相除而没有余数。如果它们不能被除而没有余数,它将重新启动程序(return main();)。但是,每当我运行它时,我都会收到 segmentation fault: core dumped,无论是在我启动它时还是在运行它几次之后。有想法该怎么解决这个吗?

谢谢!!

【问题讨论】:

  • return main(); 请不要那样做。
  • 那我应该用什么? system() 调用?
  • return main() 基本上是对 main 的递归调用,这会让你陷入无限循环,最终会溢出堆栈。因此,分段错误。您的程序需要连续结束或循环,但通常(不是通过递归调用,因为这会溢出您的堆栈)取决于您要执行的操作。
  • 好吧,我可以转储返回的 main()。但是,如果模数为 (div1%div2!=0) 的部分失败,我应该使用什么来重新启动程序?
  • 与其重新启动程序,不如使用 while(true) 并编写程序,这样它就可以连续循环而无需再次调用自己。

标签: c++


【解决方案1】:

这是我在 cmets 中所说的一个例子。显然,你可以重构它,让它更优雅地工作(现在它有时会给你浮点异常),但它让你知道如何在不再次调用 main 的情况下做到这一点。

注意:您不需要为 NEWLINE 设置常量。 std 中已经有一个内置常量。事实上,您已经在使用该常量 (endl)。所以你可以只做 cout

    //div1
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <algorithm>
using namespace std;

#define CLS "\033[2J\033[1;1H"
#define NEWLINE "\n"

int main() {
    while(true) {
        srand(time(NULL));
        int a, div1, div2;
        div1=rand()%11;
        div2=rand()%11;
        while (div2>div1) {
            swap(div1,div2);
            continue;
        }
        if (div1%div2!=0) {
        } else {
            cout << CLS;
            cout << NEWLINE;
            do {
                cout << div1 << " / " << div2 << " = ?" << endl;
                cin >> a;
                cout << CLS;
                cout << NEWLINE;
                cout << "\t\tWrong!!" << endl;
                cout << NEWLINE;
            } while (a!=div1/div2);
            cout << CLS;
            cout << NEWLINE;
            cout << "\t\tCorrect!!" << endl;
            cout << NEWLINE;
            cout << "Hit enter to continue." << endl;
            cin.ignore();
            cin.get();
        }
    }
    return 0;
}

【讨论】:

  • 我做了一些不同的事情,但它具有相同的总体思路,并且似乎有效。谢谢!
【解决方案2】:

此代码可能会出现“除以 0”错误。这就是为什么你会得到错误。

“if (div1%div2!=0) {”这行似乎是错误的。 在这一行中如果 div2 == 0,那么你的代码就会崩溃。

【讨论】:

  • 这是不正确的。除以零确实是未定义的,但不会导致崩溃。您可以轻松地对此进行测试。编写一个除以0的程序。编译时编译器会警告你,但实际运行时不会崩溃。警告看起来像这样:test.cpp:12:10: warning: division by zero is undefined [-Wdivision-by-zero]
  • @EdwardL。据我了解,当您运行除以零的程序时,您将收到 SIGFPE 错误并且程序确实终止。
  • 我想它可能是编译器/系统特定的。我在 clang-600.0.57 下测试了这个,用这个版本编译时它不会崩溃,我会尝试验证看看 GNU 编译器会做什么。
  • 看来 GNU 编译器的行为略有不同,并且会像 Clang 编译器那样终止。但是,两者都会在编译期间发出警告。无论如何,这不是他的分段错误的原因。这是由对 main() 的递归调用引起的。
猜你喜欢
  • 2016-03-19
  • 1970-01-01
  • 2022-01-14
  • 2017-02-25
  • 2016-07-12
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多