2
(gdb) list 95, 195
95      int BishopArranger::FillAndRecurse(int cursor)
96      {
97              if (cursor == _solutionVec.size())
98              {
99                      return 1;
100             }
101
102             unordered_set<tuple<int, int>> candidates = GetCandidates(cursor); //kn
103             if (candidates.empty())
104             {
105                     return 0;
106             }
107
108             int sum = 0;
109             for (unordered_set<tuple<int, int>>::iterator it = candidates.begin(); it != candidates.end(); it++) //n^2
110             {
111                     _solutionVec[cursor] = *it;
112                     sum += FillAndRecurse(cursor+1); //k recursions, each being kn
113             }
114             //kn^3
115             return sum;
116     }
117
118     void ConstructBoard(int k, int n)
119     {
120             BOARD = unordered_set<tuple<int, int>>();
121             for (int i=0; i<n; i++)
122             {
123                     for (int j=0; j<n; j++)
124                     {
125                             BOARD.insert(tuple<int, int>(i, j));
126                     }
127             }
128     }
129
130     int BishopArranger::Solution(int k, int n)
131     {
132             if (n == 0)
133             {
134                     return 0;
135             }
136
137             ConstructBoard(k, n);
138             _solutionVec = vector<tuple<int, int>>(k);
139             return FillAndRecurse(0);
140     }
(gdb) next
102             unordered_set<tuple<int, int>> candidates = GetCandidates(cursor); //kn
(gdb) print this
$2 = (BishopArranger * const) 0x22a5f0
(gdb) step

Program received signal SIGILL, Illegal instruction.
0x0000000100401bb7 in BishopArranger::GetCandidates (this=0x0, cursor=0)
    at ./src/bishop_arranger/BishopArranger.cc:84
84      {

我写了一些代码并对其进行了一些(谷歌)测试,却发现它失败了:程序完成并给出了错误的输出。所以我很自然地启动了 gdb 并尝试调试我的测试。

有趣的是,就在我进入 GetCandidates(int cursor) 函数之前,在第 102 行,“this”指针很好:

(gdb) print this

$2 = (BishopArranger * const) 0x22a5f0

然后我在函数中做了一个“步骤”,它立即给了我一个异常,抱怨“this”为空(this=0x0):

(gdb) step

Program received signal SIGILL, Illegal instruction.
0x0000000100401bb7 in BishopArranger::GetCandidates (this=0x0, cursor=0)
    at ./src/bishop_arranger/BishopArranger.cc:84
84      {

这有多荒谬?我确定这仅在我通过使用 Google Test 编写的测试用例进行调试时发生,而不是在我运行它们时发生:

[ RUN      ] Solution.TinyBoardTinyK
./test/bishop_arranger/UnitTests.cc:14: Failure
Value of: bishopArranger.Solution(2, 2)
  Actual: 12
Expected: 4
[  FAILED  ] Solution.TinyBoardTinyK (0 ms)

如您所见,当我运行 Google 测试时,产生了不正确的输出 12。尽管程序未能通过断言,但它毫无例外地完成了。

您可能感兴趣的一些信息:

1,我的程序中只有一个线程,尽管 Google Test 使用 pthreads 来并行执行测试,根据他们的文档(它说不能保证某些测试在其他测试之前完成)。

不确定这与我的情况是否相关,因为我的每个测试都有自己的对象,并且没有通用的设置/拆卸部分,因此一个测试中的对象不太可能被另一个测试破坏。他们看起来像:

TEST(Solution, BoundaryCondition)
{
    BishopArranger bishopArranger;
    EXPECT_EQ(0, bishopArranger.Solution(0, 0));
}


TEST(Solution, TinyBoardTinyK)
{
    BishopArranger bishopArranger;
    EXPECT_EQ(4, bishopArranger.Solution(2, 2));
}


TEST(Solution, SmallBoardSmallK)
{
    BishopArranger bishopArranger;
    EXPECT_EQ(260, bishopArranger.Solution(4, 4));
}

2、平台:CYGWIN_NT-6.1;g++ 用于编译谷歌测试和这个程序:4.8.3(是的,我遵循谷歌测试的文档并使用与我的 c++ 程序相同版本的编译器从源代码编译以避免潜在问题);gdb 版本:7.8

提前感谢您的投入!

4

2 回答 2

1

我相信这是一个埋在 cygwin 中某个地方的错误,因为我后来在一个真正的 Linux 系统上尝试了同样的事情,并且它按预期工作得很好。我学到的教训:如果你想做严肃的开发,远离 Cygwin。

于 2015-02-28T17:50:16.030 回答
0
BishopArranger::GetCandidates (this=0x0, ...)

这也将发生在尚未构造的静态 C++ 对象中。但不清楚你是否正在遭受这个问题。

对于那种混乱,请参阅“静态初始化顺序惨败”。在 GCC 下,用于init_priority构造它们。在 Windows 下,用于init_seg创建它们。

于 2015-08-15T10:38:47.273 回答