调试 C++ 期间的段错误
Segmentation Fault during Debugging C++
所以,有一个任务,我需要使用堆栈解决 N-Queens* 问题。
*N 皇后问题:你有一个棋盘,里面有 N rows/columns/queens。您必须放置每个皇后,使其不能攻击棋盘上的任何其他皇后。
我创建了一个 Queen class 只是为了存储放置的每个有效 Queen 的行和列位置,并且工作正常。据我所知,我所有的排序和检查逻辑也都很好。但是,无论是在 main 还是我的 solve 函数中,我都遇到了分段错误,但只有在调试时才会出现。当运行正常时,它就退出了。不幸的是,我的调试器不允许我逐行执行,但我已经手动完成了,但仍然无法解决这个问题。
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 是一个 bool 函数,它只根据行进行检查,我将其作为 int 传入,然后 return true/false 用于循环。
首先,您的代码中存在一个明显的问题,会立即导致堆栈溢出运行。您递归调用求解函数的方式:
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
如果程序正常执行,return代码应该为零。
所以,有一个任务,我需要使用堆栈解决 N-Queens* 问题。
*N 皇后问题:你有一个棋盘,里面有 N rows/columns/queens。您必须放置每个皇后,使其不能攻击棋盘上的任何其他皇后。
我创建了一个 Queen class 只是为了存储放置的每个有效 Queen 的行和列位置,并且工作正常。据我所知,我所有的排序和检查逻辑也都很好。但是,无论是在 main 还是我的 solve 函数中,我都遇到了分段错误,但只有在调试时才会出现。当运行正常时,它就退出了。不幸的是,我的调试器不允许我逐行执行,但我已经手动完成了,但仍然无法解决这个问题。
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 是一个 bool 函数,它只根据行进行检查,我将其作为 int 传入,然后 return true/false 用于循环。
首先,您的代码中存在一个明显的问题,会立即导致堆栈溢出运行。您递归调用求解函数的方式:
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
如果程序正常执行,return代码应该为零。