【问题标题】:Segmentation Fault during Debugging C++调试 C++ 期间的分段错误
【发布时间】:2015-12-23 14:45:38
【问题描述】:

所以,有一个任务,我需要使用堆栈解决 N-Queens* 问题。

*N-Queens 问题:您有一个包含 N 行/列/皇后的棋盘。您必须放置每个皇后,使其无法攻击板上的任何其他皇后。

我创建了一个 Queen 类,只是为了存储每个放置的有效皇后的行和列位置,这工作正常。据我所知,我所有的排序和检查逻辑也很好。但是,无论是在 main 函数还是我的求解函数中,我都会遇到分段错误,但只有在调试时才会出现。正常运行时,它就退出了。不幸的是,我的调试器不允许我逐行执行,但我已经手动完成了,但仍然无法解决这个问题。

void solve(int k, int N)
{
stack<Queen> queenStack;
if(k == N)
    {
    while(!queenStack.empty())
        {
        cout << queenStack.top().rowPos << ", " << queenStack.top().colPos << endl;
        queenStack.pop();
        }//end while 
    }//endif

else
    {
    for (int i = 0;i < N; i++)
        {
        if (isSafe(k,i))
            {
            Queen queen(k,i);
            queenStack.push(queen);
            solve(k++,N);
            }//end if
        else
            {
            if(queenStack.empty())
                {
                break;
                }//end if
            else
                {
                queenStack.pop();
                k--;
                }//end else
            }//end else
         }//end for
    }//end else
}//end void

然后是我的主要:

int main()
{
int N = 0;
cout << "Please pick an integer 3 or greater and less than whatever you think won't crash your computer." << endl;
cin >> N;
while (N < 3)
    {
    cout << "Please pick an integer 3 or greater and less than whatever you think won't crash your computer." <<
    endl;
    cin >> N;
    }//end while
solve(0,N);
return 0;
}//end main

我的 ifSafe 是一个布尔函数,它只根据行进行检查,我将其作为 int 传入,然后返回循环的真/假。

【问题讨论】:

  • queenStack 是 solve 函数的本地函数。在递归之前添加它不会影响该调用。
  • 所以我需要在main中创建堆栈,将它传递给函数,然后使用函数添加到它?如果我理解正确的话。

标签: c++ class vector segmentation-fault stack


【解决方案1】:

首先,您的代码中有一个明显的问题会立即导致堆栈溢出。递归调用求解函数的方式:

solve(k++,N);

将首先调用solve,然后递增k。所以solve(0, N) 调用solve(0, N),而后者又调用solve(0, N) 导致堆栈溢出。没有副作用或任何外部变量会影响 solve 并使其在使用相同的参数时表现不同。

我不完全理解你的解决方案,所以我不能告诉你如何解决它,但很可能你的意图是让 queenStack 在调用中可见,在这种情况下,使它是全局的,或者通过引用将其传递给solve。

现在了解为什么在调试器之外运行它时它可以正常运行。我的猜测是您使用某种非 Windows 系统(mac 或 linux)并从终端运行它。这样程序仍然会崩溃,但不会以任何明显的方式显示出来。查看是否成功完成的方法是在执行程序后打印$?:

a@a-dev:~$ ./crash_me
a@a-dev:~$ echo $?
1

如果程序正常执行,返回码应该为零。

【讨论】:

    猜你喜欢
    • 2017-07-04
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-23
    相关资源
    最近更新 更多