分段错误-尝试完成Euler 4

Segmentation fault - attempting to complete Euler 4

本文关键字:Euler 错误 分段      更新时间:2023-10-16

我正在努力解决C++中的欧拉问题(作为一种学习工具(,我要解决问题4,如何找到两个三位数整数的最大回文乘积。但是,当我运行程序时,我会收到错误Segmentation fault (core dumped)。我不确定我做了什么导致了这种情况,有人能向我解释一下吗?

这是我的代码:

#include <iostream>
#include <string>
using namespace std;
bool palindrome(int x){
    string x_str = to_string(x);
    string x_str_rev = "";
    for(unsigned int i = x_str.length(); i > 0; i++){
        x_str_rev += x_str[i];
    };
    if(x_str == x_str_rev){
        return true;
    }
    else{
        return false;
    };
}
int main(){
    for(int i = 999; i > 100; i--){
        for(int x = 999; x > 100; x--){
            if(palindrome(i * x)){
                cout << i * x << endl;
                return 0;
            }
        };
    };
}

palindromefor循环的标准看起来不正确:

for(unsigned int i = x_str.length(); i > 0; i++){
    x_str_rev += x_str[i];
};

我想你是想把绳子倒过来的吧?在上面的代码片段中,您所做的是从字符串的末尾开始,然后进入无人区,这将导致未定义的行为。

你应该使用这样一个递减循环:

for(unsigned int i = x_str.length() - 1; i >= 0; --i){
    x_str_rev += x_str[i];
};
for(unsigned int i = x_str.length(); i > 0; i++)

这是问题线。

查看执行此循环时变量i会发生什么。试着一步一步地运行它。

for(unsigned int i = x_str.length(); i > 0; i++){
    std::cerr << "i =" << i << std::endl;
    x_str_rev += x_str[i];
};

学会发现索引问题是解决此类segfault问题的重要组成部分。

更改

for (unsigned int i = x_str.length(); i > 0; i++){

for (unsigned int i = x_str.length()-1; i >= 0; --i){
                      ^^^^^^^^^^^^^^^^    ^^    ^^^

您有一个循环,它对字符串中的字符进行迭代。但是您递增i而不是递减:

for(unsigned int i = x_str.length(); i > 0; i++)

这就是

  1. 无限循环
  2. 访问x_str中的无效索引。这就是你犯错的原因

您必须从length()-1开始,然后使用i--才能使其工作。

将来:学习如何使用调试器。它将很容易地向您显示发生分段故障或类似故障的代码行。如果你对编程很认真的话,这是一项你无论如何都需要掌握的技能。

例如,如果您在Linux上,您可以执行以下操作:

gdb your-program
(gdb) run 
(gdb) bt

它会向您显示segfault发生的位置(如果使用调试符号编译而不进行优化(。